<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/~avsm2/fcs/default.xsl"?>
<fr:tree xmlns:fr="http://www.forester-notes.org" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" root="true" base-url="/~avsm2/fcs/">
  <fr:frontmatter>
    <fr:authors>
      <fr:author>
        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
      </fr:author>
      <fr:contributor>Lawrence C. Paulson</fr:contributor>
      <fr:contributor>David Allsopp</fr:contributor>
      <fr:contributor>Jon Ludlam</fr:contributor>
      <fr:contributor>Jeremy Yallop</fr:contributor>
    </fr:authors>
    <fr:date>
      <fr:year>2026</fr:year>
      <fr:month>10</fr:month>
      <fr:day>1</fr:day>
    </fr:date>
    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/index/</fr:uri>
    <fr:display-uri>index</fr:display-uri>
    <fr:route>/~avsm2/fcs/index/</fr:route>
    <fr:title text="Foundations of Computer Science (2026–27 draft)">Foundations of Computer Science (2026–27 draft)</fr:title>
  </fr:frontmatter>
  <fr:mainmatter>
    <html:p><html:strong>Draft:</html:strong> this is a work-in-progress edition of the notes for the
2026–27 academic year, and not yet the final version.</html:p>
    <html:p>See also the <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>, the <fr:link href="/~avsm2/fcs/focs-topics/" title="Topic index" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topics/" display-uri="focs-topics" type="local">topic index</fr:link> and the <fr:link href="/~avsm2/fcs/focs-all-exercises/" title="All exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-all-exercises/" display-uri="focs-all-exercises" type="local">collected exercises</fr:link>.</html:p>
    <html:p>This course has two aims. The first is to teach programming. The second is to
present some fundamental principles of computer science, especially algorithm
design. Most students will have some programming experience already, but there
are few people whose programming cannot be improved through greater knowledge
of basic principles. Please bear this point in mind if you have extensive
experience and find parts of the course rather slow.</html:p>
    <html:p>The programming in this course is based on the language <fr:link href="https://ocaml.org/" type="external">OCaml</fr:link>
and mostly concerns the functional programming style. Functional programs tend
to be shorter and easier to understand than their counterparts in conventional
languages such as C. In the space of a few weeks, we shall cover many
fundamental data structures and learn basic methods for estimating efficiency.</html:p>
    <html:p>The first thing you will notice about this course is that there is an
<html:em>interactive</html:em> version hosted online at <fr:link href="https://hub.cl.cam.ac.uk/" type="external">hub.cl.cam.ac.uk</fr:link>, where you
can login with your Cambridge Raven identity and edit the code fragments in
your browser.  You are encouraged to do so — such edits will only persist in
your session, and will help you to explore the world of functional programming.
If you are using the web-based version, then you need to know a few concepts:</html:p>
    <html:ul><html:li>The notebook consists of a sequence of textual and code snippets.</html:li>
  <html:li>The code snippets can be executed individually, and will “remember” the
  results of the previous snippets.</html:li>
  <html:li>To begin with, click on <html:code>Cell</html:code> / <html:code>Run All</html:code> in the menu to execute the
  entire notebook.</html:li>
  <html:li>You can later double click on any cell and modify its contents, and
  press <html:code>Shift+Enter</html:code> to reevaluate its contents.  This will only modify
  the current cell, so you will have to <html:code>Run All</html:code> again to see the effects
  on the whole notebook.</html:li>
  <html:li>While editing longer snippets, you can also press <html:code>Shift+Tab</html:code> while
  typing to get more documentation hints about the code you are writing.</html:li></html:ul>
    <html:p>This course is lectured by <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link> and Jon Ludlam.  These notes
are translated from Lawrence C.
Paulson’s earlier course on Standard ML, which had credits to David Allsopp,
Stuart Becker, Gavin Bierman, Chloë Brown, Silas Brown, Qi Chen, David
Cottingham, William Denman, Robert Harle, Daniel Hulme, Frank King, Jack
Lawrence-Jones, Joseph Lord, Dimitrios Los, Farhan Mannan, James Margetson,
David Morgan, Alan Mycroft, Sridhar Prabhu, Frank Stajano, Alex Trifanov,
Thomas Tuerk, Xincheng Wang, Philip Withnall and Assel Zhiyenbayeva for
pointing out errors.  The current notes were ported to OCaml in 2019 by Anil
Madhavapeddy, David Allsopp, and Jon Ludlam and subsequently edited by
Jeremy Yallop. We thank Richard Sharp, Srinivasan Keshav, Ambroise
Lafont, Vojtěch Tvrdík, Jeremy Yallop, Alexandra W. Chadwick and
Richard Mortier for further feedback and corrections since 2020.</html:p>
    <html:p>Some books that are complementary to this course are:</html:p>
    <html:ul>
      <html:li><fr:link href="http://ocaml-book.com/" type="external"><html:em>OCaml from the Very Beginning</html:em></fr:link> by John Whitington.</html:li>
    </html:ul>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/</fr:uri>
        <fr:display-uri>focs-intro</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-intro/</fr:route>
        <fr:title text="Introduction to Programming">Introduction to Programming</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-basic-concepts/</fr:uri>
            <fr:display-uri>focs-basic-concepts</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-basic-concepts/</fr:route>
            <fr:title text="Basic Concepts in Computer Science">Basic Concepts in Computer Science</fr:title>
          </fr:frontmatter>
          <fr:mainmatter><html:ul><html:li>Computers: a child can use them; <html:strong>nobody</html:strong> can fully understand them!</html:li>
  <html:li>We can master complexity through levels of abstraction.</html:li>
  <html:li>Focus on 2 or 3 levels at most!</html:li></html:ul><html:p><html:strong>Recurring issues:</html:strong></html:p><html:ul><html:li><html:em>what services</html:em> to provide at each level</html:li>
  <html:li><html:em>how to implement</html:em> them using lower-level services</html:li>
  <html:li><html:em>the interface</html:em> that defines how the two levels should communicate</html:li></html:ul><html:p>A basic concept in computer science is that large systems can only be
understood in levels, with each level further subdivided into functions or
services of some sort. The interface to the higher level should supply the
advertised services. Just as important, it should block access to the means by
which those services are implemented. This <html:em>abstraction barrier</html:em> allows one
level to be changed without affecting levels above. For example, when a
manufacturer designs a faster version of a processor, it is essential that
existing programs continue to run on it. Any differences between the old and
new processors should be invisible to the program.</html:p><html:p>Modern processors have elaborate specifications, which still sometimes leave
out important details. In the old days, you then had to consult the circuit
diagrams.</html:p>

<fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link></fr:author></fr:authors><fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/</fr:uri><fr:display-uri>focs-dates</fr:display-uri><fr:route>/~avsm2/fcs/focs-dates/</fr:route><fr:title text="Example 1: Dates">Example 1: Dates</fr:title></fr:frontmatter><fr:mainmatter><html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">Abstract level</fr:link>: dates over a certain interval</html:li>
  <html:li>Concrete level: could be 6 characters: <html:code>YYMMDD</html:code> (where each character is represented by 8 bits)</html:li>
  <html:li>Date crises caused by <html:strong>inadequate</html:strong> internal formats:
    <html:ul><html:li>Digital’s PDP-10: using 12-bit dates (good for at most 11 years)</html:li>
      <html:li>2000 crisis: 48 bits could be good for lifetime of universe!</html:li></html:ul></html:li></html:ul><html:p>Digital Equipment Corporation’s date crisis occurred in 1975.  The
PDP-10 was a 36-bit mainframe computer. It represented dates using a 12-bit
format designed for the tiny PDP-8. With 12 bits, one can distinguish
<fr:tex display="inline"><![CDATA[2^{12} = 4096]]></fr:tex> days or 11 years.</html:p><html:p>Last century, the most common industry format for dates used six characters: two for the
year, two for the month and two for the day. The most common “solution” to the
year 2000 crisis is to add two further characters, thereby altering file sizes.
Others have noticed that the existing six characters consist of 48 bits,
already sufficient to represent all dates over the projected lifetime of the
universe: <fr:tex display="inline"><![CDATA[2^{48}]]></fr:tex> = <fr:tex display="inline"><![CDATA[2.8\times  10^{14}]]></fr:tex> days = <fr:tex display="inline"><![CDATA[7.7\times  10^{11}]]></fr:tex> years!</html:p><html:p>Mathematicians think in terms of unbounded ranges, but the representation we
choose for the computer usually imposes hard limits. A good programming
language like OCaml lets one easily change the representation used in the
program.  But if files in the old representation exist all over the place,
there will still be conversion problems. The need for compatibility with older
systems causes problems across the computer industry.</html:p></fr:mainmatter></fr:tree>
<fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link></fr:author></fr:authors><fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/</fr:uri><fr:display-uri>focs-floating-point</fr:display-uri><fr:route>/~avsm2/fcs/focs-floating-point/</fr:route><fr:title text="Example 2: Floating Point Numbers">Example 2: Floating Point Numbers</fr:title></fr:frontmatter><fr:mainmatter><html:p>Computers have integers like <html:code>1066</html:code> and floats like <fr:tex display="inline"><![CDATA[1.066\times  10^3]]></fr:tex>.
A floating-point number is represented by two integers.
The concept of <html:em>data type</html:em> involves:</html:p><html:ul><html:li>how a value is represented inside the computer</html:li>
  <html:li>the suite of operations given to programmers</html:li>
  <html:li>valid and invalid (or exceptional) results, such as “infinity”</html:li></html:ul><html:p>Computer arithmetic can yield <html:em>incorrect answers!</html:em></html:p><html:p>In science, numbers written with finite precision and a decimal exponent are
said to be in <html:em>standard form</html:em>. The computational equivalent is the <html:em>floating
point number</html:em>. These are familiar to anybody who has used a scientific
calculator.  Internally, a float consists of two integers.</html:p><html:p>Because of its finite precision, floating-point computations are potentially
inaccurate. To see an example, use your nearest electronic calculator to
compute <fr:tex display="inline"><![CDATA[(2^{1/10000})^{10000}]]></fr:tex>. I get <fr:tex display="inline"><![CDATA[1.99999959]]></fr:tex>! With certain computations,
the errors spiral out of control. Many programming languages fail to check
whether even integer computations fall within the allowed range: you can add
two positive integers and get a negative one!</html:p><html:p>Most computers give us a choice of precisions. In 32-bit precision, integers
typically range from <fr:tex display="inline"><![CDATA[2^{31}-1]]></fr:tex> (namely 2 147 483 647) to <fr:tex display="inline"><![CDATA[-2^{31}]]></fr:tex>; floats
are accurate to about six decimal places and can get as large as <fr:tex display="inline"><![CDATA[10^{35}]]></fr:tex> or so.
For floats, 64-bit precision is often preferred. Early languages like Fortran
required variables to be declared as <html:code>INTEGER</html:code>, <html:code>REAL</html:code> or <html:code>COMPLEX</html:code> and barred
programmers from mixing numbers in a computation. Nowadays, programs handle
many different kinds of data, including text and symbols. The concept of a
<html:em>data type</html:em> can ensure that different types of data are not combined in a
senseless way.</html:p><html:p>Inside the computer, all data are stored as bits. In most programming
languages, the compiler uses types to generate correct machine code, and types
are not stored during program execution. In this course, we focus almost
entirely on programming in a high-level language: OCaml.</html:p></fr:mainmatter></fr:tree>
</fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-goals-of-programming/</fr:uri>
            <fr:display-uri>focs-goals-of-programming</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-goals-of-programming/</fr:route>
            <fr:title text="Goals of Programming">Goals of Programming</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>to describe a computation so that it can be done <html:strong>mechanically</html:strong>:
    <html:ul><html:li>Expressions compute values.</html:li>
      <html:li>Commands cause effects.</html:li></html:ul></html:li>
  <html:li>to do so efficiently and <html:strong>correctly</html:strong>, giving the right answers quickly</html:li>
  <html:li>to allow easy modification as needs change
    <html:ul><html:li>Through an orderly <html:strong>structure</html:strong> based on <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstraction principles</fr:link></html:li>
      <html:li>Such as modules or classes</html:li></html:ul></html:li></html:ul>
            <html:p>Programming <html:em>in-the-small</html:em> concerns the writing of code to do simple, clearly
defined tasks. Programs provide expressions for describing mathematical
formulae and so forth. This was the original contribution of FORTRAN, the
FORmula TRANslator. Commands describe how control should flow from one part of
the program to the next.</html:p>
            <html:p>As we code layer upon layer, we eventually find ourselves programming
<html:em>in the large</html:em> : joining large modules to solve some messy task. Programming
languages have used various mechanisms to allow one part of the program to
provide interfaces to other parts. Modules encapsulate a body of code, allowing
outside access only through a programmer-defined interface. <fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local"><html:em>Abstract Data
Types</html:em></fr:link> are a simpler version of this concept, which implement a single concept
such as dates or floating-point numbers.</html:p>
            <html:p><html:em>Object-oriented programming</html:em> is the most complicated approach to modularity.
<html:em>Classes</html:em> define concepts, and they can be built upon other classes. Operations
can be defined that work in appropriately specialised ways on a family of
related classes. <html:em>Objects</html:em> are instances of classes and hold the data that is
being manipulated.</html:p>
            <html:p>This course does not cover OCaml’s sophisticated module system, which can do
many of the same things as classes. You will learn all about objects when you
study Java. OCaml includes a powerful object system, although this is not used
as much as its module system.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-why-ocaml/</fr:uri>
            <fr:display-uri>focs-why-ocaml</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-why-ocaml/</fr:route>
            <fr:title text="Why Program in OCaml?">Why Program in OCaml?</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Why program in OCaml at all?</html:p>
            <html:ul><html:li>It is interactive.</html:li>
  <html:li>It has a flexible notion of <html:em>data type</html:em>.</html:li>
  <html:li>It hides the underlying hardware: <html:em>no crashes</html:em>.</html:li>
  <html:li>Programs can easily be understood mathematically.</html:li>
  <html:li>It distinguishes naming something from <html:em>updating memory</html:em>.</html:li>
  <html:li>It manages storage for us.</html:li></html:ul>
            <html:p>Programming languages matter. They affect the reliability, security, and
efficiency of the code you write, as well as how easy it is to read, refactor,
and extend. The languages you know can also change how you think, influencing
the way you design software even when you’re not using them.</html:p>
            <html:p>What makes OCaml special is that it occupies a sweet spot in the space of
programming language designs. It provides a combination of efficiency,
expressiveness and practicality that is difficult to find matched by any other language.
“ML” was originally the meta language of the LCF (Logic for Computable Functions)
proof assistant released by Robin Milner in 1972 (at Stanford, and later at Cambridge).
ML was turned into a compiler in order to make it easier to use LCF on different machines,
and it was gradually turned into a full-fledged system of its own by the 1980s.</html:p>
            <html:p>The modern OCaml emerged in 1996, and the past twenty five years have seen OCaml
attract a significant user base with language improvements being steadily
added to support the growing commercial and academic codebases.
OCaml is therefore the outcome of years of research into programming languages,
and a good base to begin our journey into learning the foundations of computer
science.</html:p>
            <html:p>Because of its connection to mathematics, OCaml programs can be designed and
understood without thinking in detail about how the computer will run them.
Although a program can abort, it cannot crash: it remains under the control of
the OCaml system. It still achieves respectable efficiency and provides
lower-level primitives for those who need them. Most other languages allow
direct access to the underlying machine and even try to execute illegal
operations, causing crashes.</html:p>
            <html:p>The only way to learn programming is by writing and running programs. This web
notebook provides an interactive environment where you can modify the example
fragments and see the results for yourself.  You should also consider
installing OCaml on your own computer so that you try more advanced programs
locally.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-first-session/</fr:uri>
            <fr:display-uri>focs-first-session</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-first-session/</fr:route>
            <fr:title text="A first session with OCaml">A first session with OCaml</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let pi = 3.14159265358979
val pi : float = 3.14159265358979]]></html:pre>
            <html:p>The first line of this simple session is a <html:em>value declaration</html:em>. It makes the
name <html:code>pi</html:code> stand for the floating point number <html:code>3.14159</html:code>. (Such names are called
<html:em>identifiers</html:em>.)  OCaml echoes the name (<html:code>pi</html:code>) and type (<html:code>float</html:code>) of the
declared identifier.</html:p>
            <html:pre><![CDATA[# pi *. 1.5 *. 1.5
- : float = 7.06858347057702829]]></html:pre>
            <html:p>The second line computes the area of the circle with radius <html:code>1.5</html:code> using the
formula <fr:tex display="inline"><![CDATA[A = \pi  r^2]]></fr:tex>. We use <html:code>pi</html:code> as an abbreviation for <html:code>3.14159</html:code>.
Multiplication is expressed using <html:code>*.</html:code>, which is called an <html:em>infix operator</html:em>
because it is written between its two operands.</html:p>
            <html:p>OCaml replies with the computed value (about <html:code>7.07</html:code>) and its type (again <html:code>float</html:code>).</html:p>
            <html:pre><![CDATA[# let area r = pi *. r *. r
val area : float -> float = <fun>]]></html:pre>
            <html:p>To work <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstractly</fr:link>, we should provide the service “compute the area of a
circle,” so that we no longer need to remember the formula. This sort of
encapsulated computation is called a <html:em>function</html:em>. The third line declares the
function <html:code>area</html:code>. Given any floating point number <html:code>r</html:code>, it returns another
floating point number computed using the <html:code>area</html:code> formula; note that the function
has type <html:code>float -&gt; float</html:code>.</html:p>
            <html:pre><![CDATA[# area 2.0
- : float = 12.56637061435916]]></html:pre>
            <html:p>The fourth line calls the function <html:code>area</html:code> supplying <html:code>2.0</html:code> as the argument. A
circle of radius <html:code>2</html:code> has an area of about <html:code>12.6</html:code>. Note that brackets around a
function argument are not necessary.</html:p>
            <html:p>The function uses <html:code>pi</html:code> to stand for <html:code>3.14159</html:code>. Unlike what you may have seen in
other programming languages, <html:code>pi</html:code> cannot be "assigned to" or otherwise updated.
Its meaning within <html:code>area</html:code> will persist even if we issue a new <html:code>let</html:code> declaration
for <html:code>pi</html:code> afterwards.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/</fr:uri>
            <fr:display-uri>focs-npower</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-npower/</fr:route>
            <fr:title text="Raising a Number to a Power">Raising a Number to a Power</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec npower x n =
    if n = 0 then 1.0
    else x *. npower x (n - 1)
val npower : float -> int -> float = <fun>]]></html:pre>
            <html:p>Our new <html:code>npower</html:code> definition can now take additional arguments, reflected in the arrows
present in the type of <html:code>npower</html:code>; these represent <html:em>parameters</html:em> that can be passed to the
new value being defined, with the final segment being the resulting type. Thus our <html:code>npower</html:code>
type can be read as "pass in a float and integer to return a float".</html:p>
            <html:p><html:em>Mathematical Justification</html:em> (for <fr:tex display="inline"><![CDATA[x\not =0]]></fr:tex>):</html:p>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
           x^0 & = 1 \\
           x^{n+1} & = x\times  x^n.
\end {aligned}
]]></fr:tex>
            <html:p>The function <html:code>npower</html:code> raises its float argument <html:code>x</html:code> to the power <html:code>n</html:code>, a
non-negative integer. The function is <html:strong>recursive</html:strong>: it calls itself.  You
can spot a recursive function due to the <html:code>rec</html:code> keyword in the definition:
this indicates that any invocation of the function name within the function body should call itself.
This concept should be familiar from mathematics, since exponentiation is defined by the
rules shown above. You may also have seen recursion in the product rule for
differentiation: <fr:tex display="inline"><![CDATA[(u\cdot  v)' = u\cdot  v' + u'\cdot  v]]></fr:tex>. In finding the derivative of <fr:tex display="inline"><![CDATA[u\cdot  v]]></fr:tex>,
we recursively find the derivatives of <fr:tex display="inline"><![CDATA[u]]></fr:tex> and <fr:tex display="inline"><![CDATA[v]]></fr:tex>, combining them to obtain the desired result.
The recursion is meaningful because it terminates: we reduce the problem to two smaller
problems, and this cannot go on forever. The OCaml programmer uses recursion
heavily.  For <fr:tex display="inline"><![CDATA[n\geq 0]]></fr:tex>, the equation <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> yields an obvious
computation:</html:p>
            <fr:tex display="block"><![CDATA[ x^3 = x\times  x^2 = x\times  x\times  x^1 = x\times  x\times  x\times  x^0 = x\times  x\times  x ]]></fr:tex>
            <html:p>The equation clearly holds even for negative <fr:tex display="inline"><![CDATA[n]]></fr:tex>. However, the corresponding
computation runs forever:</html:p>
            <fr:tex display="block"><![CDATA[ x^{-1} = x\times  x^{-2} = x\times  x\times  x^{-3}=\cdots  ]]></fr:tex>
            <html:p>Note that the function <html:code>npower</html:code> contains both an integer constant (<html:code>0</html:code>) and a
floating point constant (<html:code>1.0</html:code>). The decimal point makes all the difference.
OCaml will notice and ascribe different meaning to each type of constant.</html:p>
            <html:pre><![CDATA[# let square x = x *. x
val square : float -> float = <fun>]]></html:pre>
            <html:p>Now for a tiresome but necessary aside. In most languages, the types of
arguments and results must always be specified. OCaml is unusual that it normally
infers the types itself. However, sometimes it is useful to supply a hint to
help you debug and develop your program. OCaml will still infer the types even if you don’t specify them, but in some cases
it will use a more inefficient function than a specialised one. Some languages
have just one type of number, converting automatically between different
formats; this is slow and could lead to unexpected rounding errors.  Type
constraints are allowed almost anywhere. We can put one on any occurrence of x
in the function.</html:p>
            <html:pre><![CDATA[# let square (x : float) = x *. x
val square : float -> float = <fun>]]></html:pre>
            <html:p>Or we can constrain the type of the function’s result:</html:p>
            <html:pre><![CDATA[# let square x : float = x *. x
val square : float -> float = <fun>]]></html:pre>
            <html:p>OCaml treats the equality and comparison test specially. Expressions like <html:code>if x = y then</html:code> …
are allowed provided <html:code>x</html:code> and <html:code>y</html:code> have the same type and equality testing is
possible for that type. (We discuss <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local">equality</fr:link> further in a later lecture.)
Note that <html:code>x &lt;&gt; y</html:code> is OCaml for <fr:tex display="inline"><![CDATA[x\not =y]]></fr:tex>.</html:p>
            <html:p>A characteristic feature of the computer is its ability to test for conditions
and act accordingly.  In the early days, a program might jump to a given
address depending on the sign of some number.  Later, John McCarthy defined
the <html:em>conditional expression</html:em> to satisfy <html:code>if true then x else y = x</html:code> and
<html:code>if false then x else y = y</html:code>.</html:p>
            <html:p>OCaml evaluates the expression <html:code>if</html:code> <fr:tex display="inline"><![CDATA[B]]></fr:tex> <html:code>then</html:code> <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> <html:code>else</html:code> <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> by first evaluating <fr:tex display="inline"><![CDATA[B]]></fr:tex>.
If the result is <html:code>true</html:code> then OCaml evaluates <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and otherwise <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>.  Only one
of the two expressions <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> is evaluated!  If both were evaluated,
then recursive functions like <html:code>npower</html:code> above would run forever.</html:p>
            <html:p>The <html:code>if</html:code>-expression is governed by an expression of type <html:code>bool</html:code>, whose two
values are <html:code>true</html:code> and <html:code>false</html:code>.  In modern programming languages, tests are not
built into “conditional branch” constructs but can just be part of normal expressions.
Tests, or <html:em>Boolean expressions,</html:em> can be expressed using relational operators
such as <html:code>&lt;</html:code> and <html:code>=</html:code>. They can be combined using the Boolean operators for
negation (<html:code>not</html:code>), conjunction (written as <html:code>&amp;&amp;</html:code>) and disjunction (written as <html:code>||</html:code>).  New
properties can be declared as functions: here, to test whether an integer is
even, for example:</html:p>
            <html:pre><![CDATA[# let even n = n mod 2 = 0
val even : int -> bool = <fun>]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/</fr:uri>
            <fr:display-uri>focs-power</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-power/</fr:route>
            <fr:title text="Efficiently Raising a Number to a Power">Efficiently Raising a Number to a Power</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec power x n =
    if n = 1 then x
    else if even n then
      power (x *. x) (n / 2)
    else
      x *. power (x *. x) (n / 2)
val power : float -> int -> float = <fun>]]></html:pre>
            <html:p>
              <html:em>Mathematical Justification</html:em>
            </html:p>
            <fr:tex display="block"><![CDATA[\begin {aligned}
           x^1 & = x \\
           x^{2n} & = (x^2)^n  \\
           x^{2n+1} & = x\times (x^2)^n.
\end {aligned}]]></fr:tex>
            <html:p>For large <html:code>n</html:code>, computing powers using <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> is too slow to
be practical.  The equations above are much faster. Example:</html:p>
            <fr:tex display="block"><![CDATA[ 2^{12} = 4^6 = 16^3 = 16\times  256^1 = 16\times  256 = 4096. ]]></fr:tex>
            <html:p>Instead of <html:code>n</html:code> multiplications, we need at most <fr:tex display="inline"><![CDATA[2\lg  n]]></fr:tex> multiplications,
where <fr:tex display="inline"><![CDATA[\lg  n]]></fr:tex> is the logarithm of <fr:tex display="inline"><![CDATA[n]]></fr:tex> to the base <fr:tex display="inline"><![CDATA[2]]></fr:tex>.</html:p>
            <html:p>We use the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>even</html:code></fr:link>, declared previously, to test whether the
exponent is even.  Integer division (<html:code>/</html:code>) truncates its result to an
integer: dividing <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex> by 2 yields <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
            <html:p>A recurrence is a useful computation rule only if it is bound to terminate.
If <fr:tex display="inline"><![CDATA[n>0]]></fr:tex> then <fr:tex display="inline"><![CDATA[n]]></fr:tex> is smaller than both <fr:tex display="inline"><![CDATA[2n]]></fr:tex> and <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex>.  After enough
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive calls</fr:link>, the exponent will be reduced to <fr:tex display="inline"><![CDATA[1]]></fr:tex>.  The equations also hold
if <fr:tex display="inline"><![CDATA[n\leq 0]]></fr:tex>, but the corresponding computation runs forever.</html:p>
            <html:p>Our reasoning assumes arithmetic to be <html:em>exact</html:em>. Fortunately, the calculation is
well-behaved using floating-point.</html:p>
            <html:p>Computer numbers have a finite range, which if exceeded results in the
integer wrapping around.  You will understand this behaviour more as you
learn about computer architecture and how modern systems represent
numbers in memory.</html:p>
            <html:p>If integers and floats must be combined in a calculation, OCaml provides functions
to convert between them:</html:p>
            <html:pre><![CDATA[# int_of_float 3.14159
- : int = 3
# float_of_int 3
- : float = 3.]]></html:pre>
            <html:p>OCaml’s libraries are organised using “modules”, so we may use compound
identifiers such as <html:code>Float.of_int</html:code> to refer to library functions. There
are many thousands of library functions available in the OCaml ecosystem,
including text-processing and operating systems functions in addition to the
usual numerical ones.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/</fr:uri>
            <fr:display-uri>focs-ex-1</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-1/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/</fr:uri>
                <fr:display-uri>focs-ex-1-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-1/</fr:route>
                <fr:title text="Two-digit year windowing">Two-digit year windowing</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>One solution to the <fr:link href="/~avsm2/fcs/focs-dates/" title="Example 1: Dates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/" display-uri="focs-dates" type="local">year 2000 bug</fr:link> involves storing years as two digits, but interpreting them such
that 50 means 1950 and 49 means 2049. Comment on the merits and demerits of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-2/</fr:uri>
                <fr:display-uri>focs-ex-1-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-2/</fr:route>
                <fr:title text="Comparing and adding years">Comparing and adding years</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Using the date representation of <fr:link href="/~avsm2/fcs/focs-ex-1-1/" title="Exercises › Two-digit year windowing" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/" display-uri="focs-ex-1-1" type="local">the previous exercise</fr:link>, code OCaml functions to (a) compare two
years (b) add/subtract some given number of years from another year.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-3/</fr:uri>
                <fr:display-uri>focs-ex-1-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-3/</fr:route>
                <fr:title text="Redundant conditionals">Redundant conditionals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Why would no experienced programmer write an expression of the form <html:code>if</html:code> … <html:code>then true else false</html:code>?
What about expressions of the form <html:code>if</html:code> … <html:code>then false else true</html:code>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-4/</fr:uri>
                <fr:display-uri>focs-ex-1-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-4/</fr:route>
                <fr:title text="Type inference in power">Type inference in power</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Functions <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> both return a <html:code>float</html:code>. The definition of <html:code>npower</html:code> returns the float
value <html:code>1.0</html:code> in its base case. The definition of <html:code>power</html:code> does not, so how does the OCaml type checker
know that <html:code>power</html:code> returns a <html:code>float</html:code>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-5/</fr:uri>
                <fr:display-uri>focs-ex-1-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-5/</fr:route>
                <fr:title text="Floating-point error by repeated addition">Floating-point error by repeated addition</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Because computer arithmetic is based on binary numbers, simple decimals such as 0.1 often cannot be
represented exactly. Write a function <html:code>mul</html:code> that performs the computation</html:p>
                <fr:tex display="block"><![CDATA[\underbrace {x+x+\cdots +x}_{n}]]></fr:tex>
                <html:p>where <fr:tex display="inline"><![CDATA[x]]></fr:tex> has type <html:code>float</html:code>. (It is essential to use repeated addition rather than multiplication!)</html:p>
                <html:p>The value computed with <html:code>n = 10000</html:code> and <html:code>x = 0.1</html:code> may print as
<html:code>1000.0</html:code>, which looks exact. If that happens, then evaluate the
expression <html:code>mul 0.1 10000 -. 1000.0</html:code></html:p>
                <html:p>An error of this type has been blamed for the failure of an American Patriot Missile battery to
intercept an incoming Iraqi missile during the <fr:link href="https://en.wikipedia.org/wiki/MIM-104_PatriotFailure_at_Dhahran" type="external">first Gulf War</fr:link>.
The missile hit an American Army barracks, killing 28.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-6/</fr:uri>
                <fr:display-uri>focs-ex-1-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-6/</fr:route>
                <fr:title text="Golden ratio instability">Golden ratio instability</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another example of the <fr:link href="/~avsm2/fcs/focs-floating-point/" title="Example 2: Floating Point Numbers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/" display-uri="focs-floating-point" type="local">inaccuracy of floating-point arithmetic</fr:link> takes the golden ratio
<fr:tex display="inline"><![CDATA[\phi \approx 1.618\ldots ]]></fr:tex> as its starting point:</html:p>
                <fr:tex display="block"><![CDATA[\gamma _0 = \frac {1+\sqrt 5}{2} \quad \text {and}\quad \gamma _{n+1} = \frac {1}{\gamma _n-1}.]]></fr:tex>
                <html:p>In theory, it is easy to prove that <fr:tex display="inline"><![CDATA[\gamma _n=\cdots  = \gamma _1 = \gamma _0]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>. Code this
computation in OCaml and report the value of <fr:tex display="inline"><![CDATA[\gamma _{50}]]></fr:tex>. <html:em>Hint:</html:em> in OCaml, <fr:tex display="inline"><![CDATA[\sqrt 5]]></fr:tex> is expressed
as <html:code>sqrt 5.0</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion/</fr:uri>
        <fr:display-uri>focs-recursion</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-recursion/</fr:route>
        <fr:title text="Recursion and Efficiency">Recursion and Efficiency</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-expression-evaluation/</fr:uri>
            <fr:display-uri>focs-expression-evaluation</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-expression-evaluation/</fr:route>
            <fr:title text="Expression Evaluation">Expression Evaluation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Expression evaluation concerns expressions and the values they return. This
view of computation may seem to be too narrow. It is certainly far removed from
computer hardware, but that can be seen as an advantage. For the traditional
concept of computing solutions to problems, expression evaluation is entirely
adequate.</html:p>
            <html:p>Starting with <fr:tex display="inline"><![CDATA[E_0]]></fr:tex>, the expression <fr:tex display="inline"><![CDATA[E_i]]></fr:tex> is reduced to <fr:tex display="inline"><![CDATA[E_{i+1}]]></fr:tex> until this
process concludes with a value <fr:tex display="inline"><![CDATA[v]]></fr:tex>.  A <html:em>value</html:em> is something like a number
that cannot be further reduced.</html:p>
            <html:p>We write <fr:tex display="inline"><![CDATA[E \rightarrow  E']]></fr:tex> to say that <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:em>reduced</html:em> to <fr:tex display="inline"><![CDATA[E']]></fr:tex>.
Mathematically, they are equal: <fr:tex display="inline"><![CDATA[E=E']]></fr:tex>, but the computation goes from <fr:tex display="inline"><![CDATA[E]]></fr:tex> to
<fr:tex display="inline"><![CDATA[E']]></fr:tex> and never the other way around.</html:p>
            <html:p>Computers also interact with the outside world.  For a start, they need some
means of accepting problems and delivering solutions.  Many computer systems
monitor and control industrial processes.  This role of computers is familiar
now, but was never envisaged in the early days. Computer pioneers focused on
mathematical calculations.  Modelling interaction and control requires a notion
of <html:em>states</html:em> that can be observed and changed.  Then we can consider
updating the state by assigning to variables or performing input/output,
finally arriving at conventional programs as coded in C, for instance.</html:p>
            <html:p>For now, we remain at the level of expressions, which is usually termed
<html:em>functional programming</html:em>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/</fr:uri>
            <fr:display-uri>focs-nsum</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-nsum/</fr:route>
            <fr:title text="Summing the first n integers">Summing the first n integers</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec nsum n =
    if n = 0 then
      0
    else
      n + nsum (n - 1)
val nsum : int -> int = <fun>]]></html:pre>
            <html:p>The function call <html:code>nsum n</html:code> computes the sum <html:code>1 +</html:code> … <html:code>+ nz</html:code> rather naively, hence the
initial <html:code>n</html:code> in its name:</html:p>
            <fr:tex display="block"><![CDATA[\begin {aligned}
\text {nsum}\;3 \Rightarrow  &\; 3 + (\text {nsum}\;2) \\
               \Rightarrow  &\; 3 + (2 + (\text {nsum}\;1)) \\
               \Rightarrow  &\; 3 + (2 + (1 + (\text {nsum}\;0))) \\
               \Rightarrow  &\; 3 + (2 + (1 + 0))
\end {aligned}]]></fr:tex>
            <html:p>The nesting of parentheses is not just an artifact of
our notation; it indicates a real problem.  The function gathers up a
collection of numbers, but none of the additions can be performed until <html:code>nsum
0</html:code> is reached.  Meanwhile, the computer must store the numbers in an internal
data structure, typically the <html:em>stack</html:em>.  For large <html:code>n</html:code>, say <html:code>nsum 10000</html:code>, the
computation might fail due to stack overflow.</html:p>
            <html:p>We all know that the additions can be performed as we go along.  How do we
make the computer do that?</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/</fr:uri>
            <fr:display-uri>focs-summing-iter</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-summing-iter/</fr:route>
            <fr:title text="Iteratively summing the first n integers">Iteratively summing the first n integers</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec summing n total =
    if n = 0 then
      total
    else
      summing (n - 1) (n + total)
val summing : int -> int -> int = <fun>]]></html:pre>
            <html:p>Function <html:code>summing</html:code> takes an additional argument: a running total.  If
<html:code>n</html:code> is zero then it returns the running total; otherwise, <html:code>summing</html:code>
adds to it and continues.  The recursive calls do not nest; the additions are
done immediately.</html:p>
            <html:p>A recursive function whose computation does not nest is called
<html:em>iterative</html:em> or <html:em>tail-recursive</html:em>. Many functions can be made iterative by
introducing an argument analogous to <html:code>total</html:code>, which is often called an
<html:em>accumulator</html:em>.</html:p>
            <html:p>The gain in efficiency is sometimes worthwhile and sometimes not.  The function
<fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> is not iterative because nesting occurs whenever the exponent is odd.
Adding a third argument makes it iterative, but the change complicates the
function and the gain in efficiency is minute; for 32-bit integers, the maximum
possible nesting is 30 for the exponent <fr:tex display="inline"><![CDATA[2^{31}-1]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/</fr:uri>
            <fr:display-uri>focs-recursion-vs-iteration</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-recursion-vs-iteration/</fr:route>
            <fr:title text="Recursion vs Iteration">Recursion vs Iteration</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>“Iterative” normally refers to a loop, coded using <html:code>while</html:code> for example (see the <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local">final lecture</fr:link>)</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">Tail-recursion</fr:link> is only efficient if the compiler detects it</html:li>
  <html:li>Mainly it saves space (memory), though iterative code can also run faster</html:li>
  <html:li>Do not make programs iterative unless the gain is worth it</html:li></html:ul>
            <html:p>A <fr:link href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs" type="external">classic book</fr:link>
by Abelson and Sussman, which describes the Lisp dialect known as Scheme,
used <html:em>iterative</html:em> to mean <html:em>tail-recursive</html:em>. Iterative functions produce computations
resembling those that can be done using while-loops in conventional languages.</html:p>
            <html:p>Many algorithms can be expressed naturally using <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, but only awkwardly
using iteration. There is a story that Dijkstra sneaked recursion into Algol-60
by inserting the words “any other occurrence of the procedure name denotes
execution of the procedure.” By not using the word “recursion”, he managed to
slip this amendment past sceptical colleagues.</html:p>
            <html:p>Obsession with tail recursion leads to a coding style in which functions
have many more arguments than necessary.  Write straightforward code first,
avoiding only gross inefficiency.  If the program turns out to be too slow,
tools are available for pinpointing the cause.  Always remember KISS (Keep
It Simple, Stupid).</html:p>
            <html:p>I hope you have all noticed by now that the summation can be done even more
efficiently using the arithmetic progression formula:</html:p>
            <fr:tex display="block"><![CDATA[1+\cdots +n = n(n+1)/2]]></fr:tex>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/</fr:uri>
            <fr:display-uri>focs-sillysum</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-sillysum/</fr:route>
            <fr:title text="Silly Summing the First n Integers">Silly Summing the First n Integers</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec sillySum n =
    if n = 0 then
      0
    else
      n + (sillySum (n - 1) + sillySum (n - 1)) / 2
val sillySum : int -> int = <fun>]]></html:pre>
            <html:p>The function calls itself <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> times!  Bigger inputs mean higher costs—but
what’s the growth rate?</html:p>
            <html:p>Now let us consider how to estimate various costs associated with a program.
<html:em><fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local">Asymptotic complexity</fr:link></html:em> refers to how costs—usually time or space—grow with
increasing inputs. Space complexity can never exceed time complexity, for it
takes time to do anything with the space.  Time complexity often greatly
exceeds space complexity.</html:p>
            <html:p>The function <html:code>sillySum</html:code> calls itself twice in each <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> step.  This
function is contrived, but many mathematical formulas refer to a particular
quantity more than once.  In OCaml, we can create a local binding to a computed
value using the <html:em>local declaration</html:em> syntax. In the following expression, <html:code>y</html:code> is
computed once and used twice:</html:p>
            <html:pre><![CDATA[# let x = 2.0 in
  let y = Float.pow x 20.0 in
  y *. (x /. y)
- : float = 2.]]></html:pre>
            <html:p>You can read <html:code>let x = e1 in e2</html:code> as assigning (or "binding") the name <html:code>x</html:code> with
the value of <html:code>e1</html:code> into <html:code>e2</html:code>. Any use of <html:code>x</html:code> within <html:code>e2</html:code> will have the value of <html:code>e1</html:code>,
and <html:code>x</html:code> will only be visible in subexpressions into which it has been bound.</html:p>
            <html:p>Why do we need let bindings? Fast hardware does not make good algorithms unnecessary.
On the contrary, faster hardware magnifies the superiority of better algorithms.
Typically, we want to handle the largest inputs possible.  If we double our processing power,
what do we gain?  How much can we increase <fr:tex display="inline"><![CDATA[n]]></fr:tex>, the input to our function?</html:p>
            <html:p>With <html:code>sillySum</html:code>, we can only go from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>.  We are limited to this
modest increase because the function’s running time is proportional to <fr:tex display="inline"><![CDATA[2^n]]></fr:tex>.
With the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> defined in the previous section, we can go from <fr:tex display="inline"><![CDATA[n]]></fr:tex>
to <fr:tex display="inline"><![CDATA[2n]]></fr:tex>: we can handle problems twice as big.  With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> we can do much
better still, going from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
            <html:p>The following table (excerpted from <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">a 50-year-old book</fr:link>!)
illustrates the effect of various time complexities.  The left-hand column (dubbed "complexity")
is defind as how many milliseconds are required to process an input of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
The other entries show the maximum size of <fr:tex display="inline"><![CDATA[n]]></fr:tex> that can be processed in the given time (one
second, minute or hour).</html:p>
            <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>gain</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td><fr:tex display="inline"><![CDATA[\times  60]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td><fr:tex display="inline"><![CDATA[\times  41]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td><fr:tex display="inline"><![CDATA[\times  8]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td><fr:tex display="inline"><![CDATA[\times  4]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td><fr:tex display="inline"><![CDATA[+6]]></fr:tex></html:td></html:tr>
</html:table>
            <html:p>The table illustrates how large an input can be processed as a function
of time.  As we increase the computer time per input from one second to one
minute and then to one hour, the size of the input increases accordingly.</html:p>
            <html:p>The top two rows (complexities <fr:tex display="inline"><![CDATA[n]]></fr:tex> and <fr:tex display="inline"><![CDATA[n \lg  n]]></fr:tex>) increase rapidly: for <fr:tex display="inline"><![CDATA[n]]></fr:tex>, by
a factor of 60 per column.  The bottom two start out close together, but <fr:tex display="inline"><![CDATA[n^3]]></fr:tex> (which
grows by a factor of 3.9) pulls well away from <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> (whose growth is only
additive).  If an algorithm’s complexity is exponential then it can never
handle large inputs, even if it is given huge resources.  On the other hand,
suppose the complexity has the form <fr:tex display="inline"><![CDATA[n^c]]></fr:tex>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is a constant.  (We say
the complexity is <html:em>polynomial</html:em>.)  Doubling the argument then increases the
cost by a constant factor.  That is much better, though if <fr:tex display="inline"><![CDATA[c>3]]></fr:tex> the algorithm
may not be considered practical.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/</fr:uri>
            <fr:display-uri>focs-o-notation</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-o-notation/</fr:route>
            <fr:title text="Comparing Algorithms: O Notation">Comparing Algorithms: O Notation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Formally, define <fr:tex display="inline"><![CDATA[f(n) = O(g(n))]]></fr:tex> provided <fr:tex display="inline"><![CDATA[|f(n)| \leq  c|g(n)|]]></fr:tex> as <fr:tex display="inline"><![CDATA[n\to \infty ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[|f(n)|]]></fr:tex> is bounded for some constant <fr:tex display="inline"><![CDATA[c]]></fr:tex> and all <html:em>sufficiently large</html:em> <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:li>
  <html:li>Intuitively, look at the <html:em>most significant</html:em> term.</html:li>
  <html:li>Ignore <html:em>constant factors</html:em> as they seldom dominate and are often transitory</html:li></html:ul>
            <html:p>For example: consider <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[3n^2+34n+433]]></fr:tex>.</html:p>
            <html:p>The cost of a program is usually a complicated formula.  Often we should
consider only the most significant term.  If the cost is <fr:tex display="inline"><![CDATA[n^2 + 99n + 900]]></fr:tex>
for an input of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>, then the <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> term will eventually dominate,
even though <fr:tex display="inline"><![CDATA[99n]]></fr:tex> is bigger for <fr:tex display="inline"><![CDATA[n<99]]></fr:tex>.
The constant term <fr:tex display="inline"><![CDATA[900]]></fr:tex> may look big, but it is soon dominated by <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
            <html:p>Constant factors in costs can be ignored unless they are large.  For one thing,
they seldom make a difference: <fr:tex display="inline"><![CDATA[100n^2]]></fr:tex> will be better than <fr:tex display="inline"><![CDATA[n^3]]></fr:tex> in the long
run: or <html:em>asymptotically</html:em> to use the jargon.  Moreover, constant factors are
seldom stable.  They depend upon details such as which hardware, operating
system or programming language is being used.  By ignoring constant factors, we
can make comparisons between algorithms that remain valid in a broad range of
circumstances.</html:p>
            <html:p>The “Big O” notation is commonly used to describe efficiency—to be precise,
<html:em>asymptotic complexity</html:em>.  It concerns the limit of a function as its
argument tends to infinity.  It is an abstraction that meets the informal
criteria that we have just discussed.
In the definition, <html:em>sufficiently large</html:em> means there is some constant <fr:tex display="inline"><![CDATA[n_0]]></fr:tex>
such that <fr:tex display="inline"><![CDATA[|f(n)|\leq  c|g(n)|]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n]]></fr:tex> greater than <fr:tex display="inline"><![CDATA[n_0]]></fr:tex>.  The
role of <fr:tex display="inline"><![CDATA[n_0]]></fr:tex> is to ignore finitely many exceptions to the bound, such as the
cases when <fr:tex display="inline"><![CDATA[99n]]></fr:tex> exceeds <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation-facts/</fr:uri>
            <fr:display-uri>focs-o-notation-facts</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-o-notation-facts/</fr:route>
            <fr:title text="Simple Facts About O Notation">Simple Facts About O Notation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
 O(2g(n)) & \text { is the same as } O(g(n)) \\
 O(\log _{10}n) & \text { is the same as } O(\ln  n)  \\
 O(n^2+50n+36) & \text { is the same as } O(n^2) \\[1.5ex]
 O(n^2) & \text { is contained in }  O(n^3) \\
 O(2^n) & \text { is contained in }  O(3^n)  \\
 O(\log  n) & \text { is contained in } O(\sqrt  n)
\end {aligned}
]]></fr:tex>
            <html:p><fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> lets us reason about the costs of algorithms easily.</html:p>
            <html:ul><html:li>Constant factors such as the <fr:tex display="inline"><![CDATA[2]]></fr:tex> in <fr:tex display="inline"><![CDATA[O(2g(n))]]></fr:tex> drop out: we can use <fr:tex display="inline"><![CDATA[O(g(n))]]></fr:tex> with twice the value of <fr:tex display="inline"><![CDATA[c]]></fr:tex> in the definition.</html:li>
  <html:li>Because constant factors drop out, the base of logarithms is irrelevant.</html:li>
  <html:li>Insignificant terms drop out.  To see that <fr:tex display="inline"><![CDATA[O(n^2+50n+36)]]></fr:tex> is the same as <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>, consider that <fr:tex display="inline"><![CDATA[n^2+50n+36/n^2]]></fr:tex> converges to 1 for increasing <fr:tex display="inline"><![CDATA[n]]></fr:tex>. In fact, <fr:tex display="inline"><![CDATA[n^2+50n+36 \le  2n^2]]></fr:tex> for <fr:tex display="inline"><![CDATA[n\ge  51]]></fr:tex>, so can double the constant factor</html:li></html:ul>
            <html:p>If <fr:tex display="inline"><![CDATA[c]]></fr:tex> and <fr:tex display="inline"><![CDATA[d]]></fr:tex> are constants (that is, they are independent of <fr:tex display="inline"><![CDATA[n]]></fr:tex>) with <fr:tex display="inline"><![CDATA[0 < c < d]]></fr:tex> then</html:p>
            <html:ul><html:li><fr:tex display="inline"><![CDATA[O(n^c)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(n^d)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(c^n)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(d^n)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(n^c)]]></fr:tex></html:li></html:ul>
            <html:p>To say that <fr:tex display="inline"><![CDATA[O(c^n)]]></fr:tex> <html:em>is contained in</html:em> <fr:tex display="inline"><![CDATA[O(d^n)]]></fr:tex> means that the former gives
a tighter bound than the latter.  For example, if <fr:tex display="inline"><![CDATA[f(n)=O(2^n)]]></fr:tex> then
<fr:tex display="inline"><![CDATA[f(n)=O(3^n)]]></fr:tex> trivially, but the converse does not hold.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-complexity-classes/</fr:uri>
            <fr:display-uri>focs-complexity-classes</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-complexity-classes/</fr:route>
            <fr:title text="Common Complexity Classes">Common Complexity Classes</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li><fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is <html:em>constant</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> is <html:em>logarithmic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> is <html:em>linear</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> is <html:em>quasi-linear</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> is <html:em>quadratic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n^3)]]></fr:tex> is <html:em>cubic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(a^n)]]></fr:tex> is <html:em>exponential</html:em> (for fixed <fr:tex display="inline"><![CDATA[a]]></fr:tex>)</html:li></html:ul>
            <html:p>Logarithms grow very slowly, so <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> complexity is excellent.  Because
<fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> ignores constant factors, the base of the logarithm is
irrelevant!</html:p>
            <html:p>Under linear we might mention <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>, which occasionally is called
<html:em>quasilinear</html:em> and which scales up well for large <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
            <html:p>An example of quadratic complexity is matrix addition: forming the sum of two
<fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> matrices obviously takes <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> additions.  Matrix
multiplication is of cubic complexity, which limits the size of matrices that
we can multiply in reasonable time.  An <fr:tex display="inline"><![CDATA[O(n^{2.81})]]></fr:tex> algorithm exists, but it
is too complicated to be of much use, even though it is theoretically better.</html:p>
            <html:p>An exponential growth rate such as <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> restricts us to small values of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
Already with <fr:tex display="inline"><![CDATA[n=20]]></fr:tex> the cost exceeds one million.  However, the worst case
might not arise in normal practice.  OCaml type-checking is exponential in the
worst case, but not for ordinary programs.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sample-costs/</fr:uri>
            <fr:display-uri>focs-sample-costs</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-sample-costs/</fr:route>
            <fr:title text="Sample costs in O notation">Sample costs in O notation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Recall that <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> computes <fr:tex display="inline"><![CDATA[x^n]]></fr:tex>
by repeated multiplication while <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> naively computes the sum
<fr:tex display="inline"><![CDATA[1+\cdots +n]]></fr:tex>.  Each obviously performs <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> arithmetic operations.  Because
they are not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail recursive</fr:link>, their use of space is also <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  The function
<fr:link href="/~avsm2/fcs/focs-summing-iter/" title="Iteratively summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/" display-uri="focs-summing-iter" type="local"><html:code>summing</html:code></fr:link> is a version of <html:code>nsum</html:code> with an accumulating argument;
its iterative behaviour lets it work in constant space.  <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> spares
us from having to specify the units used to measure space.</html:p>
            <html:table>
  <html:tr><html:th>Function</html:th><html:th>Time</html:th><html:th>Space</html:th></html:tr>
  <html:tr><html:td>npower, nsum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>summing</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n(n+1)/2]]></fr:tex></html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>power</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>sillySum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[2^n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
</html:table>
            <html:p>Even ignoring constant factors, the units chosen can influence the result.
Multiplication may be regarded as a single unit of cost.  However, the cost of
multiplying two <fr:tex display="inline"><![CDATA[n]]></fr:tex>-digit numbers for large <fr:tex display="inline"><![CDATA[n]]></fr:tex> is itself an important
question, especially now that public-key cryptography uses numbers hundreds of
digits long.</html:p>
            <html:p>Few things can <html:em>really</html:em> be done in constant time or stored in constant
space.  Merely to store the number <fr:tex display="inline"><![CDATA[n]]></fr:tex> requires <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> bits.  If a
program cost is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>, then we have probably assumed that certain operations
it performs are also <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>—typically because we expect never to exceed the
capacity of the standard hardware arithmetic.</html:p>
            <html:p>With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>, the precise number of operations depends upon <fr:tex display="inline"><![CDATA[n]]></fr:tex> in a
complicated way, depending on how many odd numbers arise, so it is convenient
that we can just write <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  An accumulating argument could reduce its
space cost to <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recurrences/</fr:uri>
            <fr:display-uri>focs-recurrences</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-recurrences/</fr:route>
            <fr:title text="Some Simple Recurrence Relations">Some Simple Recurrence Relations</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Consider a function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> that has a cost we want to bound using <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link>.
A typical <html:em>base case</html:em> is <fr:tex display="inline"><![CDATA[T(1)=1]]></fr:tex>.  Some <html:em>recurrences</html:em> are:</html:p>
            <html:table>
  <html:tr><html:th>Equation</html:th><html:th>Complexity</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex></html:td></html:tr>
</html:table>
            <html:p>To analyse a function, inspect its OCaml declaration.  Recurrence equations for
the cost function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> can usually be read off.  Since we ignore constant
factors, we can give the base case a cost of one unit.  Constant work done in
the recursive step can also be given unit cost; since we only need an upper
bound, this unit represents the larger of the two actual costs.  We could use
other constants if it simplifies the algebra.</html:p>
            <html:p>For example, recall our function <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link>:</html:p>
            <html:pre><![CDATA[# let rec nsum n =
    if n = 0 then
      0
    else
      n + nsum (n - 1)
val nsum : int -> int = <fun>]]></html:pre>
            <html:p>Given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, it performs a constant amount of work (an addition and
subtraction) and calls itself recursively with argument <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  We get the
recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex>.  The closed form is
clearly <fr:tex display="inline"><![CDATA[T(n)=n+1]]></fr:tex>, as we can easily verify by substitution.  The cost is
<html:em>linear</html:em>.</html:p>
            <html:p>This function, given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, calls <html:code>nsum</html:code>, performing <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> work.
Again ignoring constant factors, we can say that this call takes exactly <fr:tex display="inline"><![CDATA[n]]></fr:tex>
units.</html:p>
            <html:pre><![CDATA[# let rec nsumsum n =
    if n = 0 then
      0
    else
      nsum n + nsumsum (n - 1)
val nsumsum : int -> int = <fun>]]></html:pre>
            <html:p>We get the recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>.  It is easy to
see that <fr:tex display="inline"><![CDATA[T(n)=(n-1)+\cdots +1=n(n-1)/2=O(n^2)]]></fr:tex>.  The cost is
<html:em>quadratic</html:em>.</html:p>
            <html:p>The function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> divides its input <fr:tex display="inline"><![CDATA[n]]></fr:tex> into two, with
the recurrence equation <fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex>.  Clearly <fr:tex display="inline"><![CDATA[T(2^n)=n+1]]></fr:tex>, so
<fr:tex display="inline"><![CDATA[T(n)=O(\log  n)]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/</fr:uri>
            <fr:display-uri>focs-ex-2</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-2/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-1/</fr:uri>
                <fr:display-uri>focs-ex-2-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-1/</fr:route>
                <fr:title text="Iterative power">Iterative power</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version of the function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-2/</fr:uri>
                <fr:display-uri>focs-ex-2-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-2/</fr:route>
                <fr:title text="Extending the complexity table">Extending the complexity table</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Add a column to the <fr:link href="/~avsm2/fcs/focs-sillysum/" title="Silly Summing the First n Integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/" display-uri="focs-sillysum" type="local">table of complexities</fr:link> from <html:em>The Design and Analysis of Computer Algorithms</html:em> with the heading <html:em>60 hours:</html:em></html:p>
                <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>60 hours</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td /></html:tr>
</html:table>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-3/</fr:uri>
                <fr:display-uri>focs-ex-2-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-3/</fr:route>
                <fr:title text="Simplifying sums in O notation">Simplifying sums in O notation</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Let <fr:tex display="inline"><![CDATA[g_1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[g_k]]></fr:tex> be functions such that <fr:tex display="inline"><![CDATA[g_i(n)\ge 0]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[k]]></fr:tex> and all sufficiently
large <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                <html:p>Show that if <fr:tex display="inline"><![CDATA[f(n) = O(a_1 g_1(n)+\cdots +a_k g_k(n))]]></fr:tex> then <fr:tex display="inline"><![CDATA[f(n) = O(g_1(n)+\cdots +g_k(n))]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-4/</fr:uri>
                <fr:display-uri>focs-ex-2-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-4/</fr:route>
                <fr:title text="A tighter recurrence bound">A tighter recurrence bound</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Find an upper bound for the recurrence given by <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+1]]></fr:tex>.  You should be
able to find a tighter bound than <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/</fr:uri>
        <fr:display-uri>focs-lists</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-lists/</fr:route>
        <fr:title text="Lists">Lists</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:pre><![CDATA[# let x = [3; 5; 9]
val x : int list = [3; 5; 9]
# let y = [(1, "one"); (2, "two")]
val y : (int * string) list = [(1, "one"); (2, "two")]]]></html:pre>
        <html:p>A <html:em>list</html:em> is an ordered series of elements; repetitions are significant.
So <html:code>[3; 5; 9]</html:code> differs from <html:code>[5; 3; 9]</html:code> and from <html:code>[3; 3; 5; 9]</html:code>.  Elements in the
list are separated with <html:code>;</html:code> when constructed, as opposed to the <html:code>,</html:code> syntax
used for fixed-length tuples.</html:p>
        <html:p>All elements of a list must have the same type.  Above we see a list of
integers and a list of <html:code>(integer, string)</html:code> pairs.  One can also have lists of
lists, such as <html:code>[[3]; []; [5; 6]]</html:code>, which has type <html:code>int list list</html:code>.</html:p>
        <html:p>In the general case, if <fr:tex display="inline"><![CDATA[x_1; \ldots ; x_n]]></fr:tex> all have the same type (say
<fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>) then the list <fr:tex display="inline"><![CDATA[[x_1;\ldots ;x_n]]]></fr:tex> has type <fr:tex display="inline"><![CDATA[(\tau )\texttt {list}]]></fr:tex>.</html:p>
        <html:p>Lists are the simplest data structure that can be used to process collections
of items.  Conventional languages use <fr:link href="/~avsm2/fcs/focs-arrays/" title="Arrays" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-arrays/" display-uri="focs-arrays" type="local"><html:em>arrays</html:em></fr:link> whose elements are
accessed using subscripting: for example, <fr:tex display="inline"><![CDATA[A[i]]]></fr:tex> yields the <fr:tex display="inline"><![CDATA[i]]></fr:tex>th element of
the array <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  Subscripting errors are a known cause of programmer grief,
however, so arrays should be replaced by higher-level data structures whenever
possible.</html:p>
        <html:pre><![CDATA[# x @ [2; 10]
- : int list = [3; 5; 9; 2; 10]
# List.rev [(1, "one"); (2, "two")]
- : (int * string) list = [(2, "two"); (1, "one")]]]></html:pre>
        <html:p>The infix operator <html:code>@</html:code> (also called <html:code>List.append</html:code>) concatenates two lists.
Also built-in is <html:code>List.rev</html:code>, which reverses a list.  These are demonstrated
in the session above.</html:p>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/</fr:uri>
            <fr:display-uri>focs-list-primitives</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-list-primitives/</fr:route>
            <fr:title text="The List Primitives">The List Primitives</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>There are two kinds of lists:</html:p>
            <html:ul><html:li><html:code>[]</html:code> represents the empty list</html:li>
  <html:li><html:code>x :: l</html:code> is the list with head <fr:tex display="inline"><![CDATA[x]]></fr:tex> and tail <fr:tex display="inline"><![CDATA[l]]></fr:tex></html:li></html:ul>
            <html:pre><![CDATA[# let nil = []
val nil : 'a list = []
# 1 :: nil
- : int list = [1]
# 1 :: 2 :: nil
- : int list = [1; 2]]]></html:pre>
            <html:p>The operator <html:code>::</html:code> (also called <html:code>List.cons</html:code> for “construct”), puts a new element on
to the head of an existing list.  While we should not be too preoccupied with
implementation details, it is essential to know that <html:code>::</html:code> is an <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
operation.  It uses constant time and space, regardless of the length of the
resulting list.  Lists are represented internally with a linked structure;
adding a new element to a list merely hooks the new element to the front of
the existing structure.  Moreover, that structure continues to denote the same
list as it did before; to see the new list, one must look at the new <html:code>::</html:code> node
(or “cons cell”) just created.  We will explain the <html:code>'a</html:code> notation in the next
section.</html:p>
            <html:p>Here we see the element <html:code>1</html:code> being consed to the front of the list <html:code>[3; 5; 9]</html:code>:</html:p>
            <fr:tex display="block"><![CDATA[\begin{array}{ccccccccccc}
:: & \to & \cdots & :: & \to &  :: & \to &  :: & \to & [] \\
\downarrow &  &        & \downarrow &  & \downarrow &  & \downarrow  \\
1     &  &        & 3     &  & 5     &  & 9
\end{array}]]></fr:tex>
            <html:p>Given a list, taking its first element (its “head”) or its list of
remaining elements (its “tail”) also takes constant time.  Each
operation just follows a link.  In the diagram above, the first down arrow
leads to the head and the leftmost right arrow leads to the tail.  Once we
have the tail, its head is the second element of the original list, etc.</html:p>
            <html:p>The tail is <html:em>not</html:em> the last element; it is the <html:em>list</html:em> of all elements
other than the head!</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/</fr:uri>
            <fr:display-uri>focs-head-tail</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-head-tail/</fr:route>
            <fr:title text="Getting at the Head and Tail">Getting at the Head and Tail</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let null = function
    | [] -> true
    | x :: l -> false
val null : 'a list -> bool = <fun>
# null []
- : bool = true
# null [1; 2; 3]
- : bool = false
# let hd (x::l) = x
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val hd : 'a list -> 'a = <fun>
# hd [1; 2; 3]
- : int = 1
# let tl (x::l) = l
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val tl : 'a list -> 'a list = <fun>
# tl [7; 6; 5]
- : int list = [6; 5]]]></html:pre>
            <html:p>The empty list has neither head nor tail.  Applying <html:code>hd</html:code> or <html:code>tl</html:code> to <html:code>[]</html:code>
is an error—strictly speaking, an <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">“exception”</fr:link>.  The function <html:code>null</html:code> can
be used to check for the empty list beforehand.  Taking a list apart using
combinations of <html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right.  Fortunately, it is seldom
necessary because of <html:em>pattern-matching</html:em>.</html:p>
            <html:p>The declaration of <html:code>null</html:code> introduces a new concept known as "pattern matching",
which we will explore more in subsequent lectures. For now, it is sufficient
to observe that <html:code>let null = function</html:code> allows for matching on the two possible values
that might be passed in as argument to <html:code>null</html:code> here: one for the empty list (for which it returns <html:code>true</html:code>)
and one for non-empty lists (for which it returns <html:code>false</html:code>).</html:p>
            <html:p>The declaration of <html:code>hd</html:code> above has only one clause, for non-empty lists.  They
have the form <html:code>x::l</html:code> and the function returns <html:code>x</html:code>, which is the head.  If you
compile this program, OCaml also prints a warning to tell us that calling
the function could raise an exception because not all possible inputs are handled,
including a counter-example (in this case, the empty list <html:code>[]</html:code>). The declaration of <html:code>tl</html:code> is similar to <html:code>hd</html:code>.</html:p>
            <html:p>These three primitive functions are <html:em>polymorphic</html:em> and allow flexibility in the
types of their arguments and results. Note their types!</html:p>
            <html:pre><![CDATA[# null
- : 'a list -> bool = <fun>
# hd
- : 'a list -> 'a = <fun>
# tl
- : 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type variables</html:em> and stand for any types. Code
written using these functions is checked for type correctness at compile time.
And this guarantees strong properties at run time, for example that the
elements of any list all have the same type.  They are usually read as their
corresponding greek characters; <html:code>'a</html:code> is "alpha", <html:code>'b</html:code> is "beta", and so on.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nlength/</fr:uri>
            <fr:display-uri>focs-nlength</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-nlength/</fr:route>
            <fr:title text="Computing the Length of a List">Computing the Length of a List</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec nlength = function
  | [] -> 0
  | x :: xs -> 1 + nlength xs
val nlength : 'a list -> int = <fun>
# nlength []
- : int = 0
# nlength [5; 6; 7]
- : int = 3]]></html:pre>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nlength }[a; b; c] \Rightarrow  &\; 1 + \text {nlength }[b; c] \\
   \Rightarrow  &\; 1 + (1 + \text {nlength }[c]) \\
   \Rightarrow  &\; 1 + (1 + (1 + \text {nlength }[])) \\
   \Rightarrow  &\; 1 + (1 + (1 + 0)) \\
   \Rightarrow  &\; \ldots  \;\; 3
\end {aligned}
]]></fr:tex>
            <html:p>Most list processing involves <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  This is a simple example; patterns
can be more complex.  Observe the use of a vertical bar <html:code>|</html:code> to separate the function’s
clauses.  We have <html:em>one</html:em> function declaration that handles two cases.
To understand its role, consider the following faulty code:</html:p>
            <html:pre><![CDATA[# let rec nlength [] = 0
Line 1, characters 17-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
_::_
val nlength : 'a list -> int = <fun>
# let rec nlength (x::xs) = 1 + nlength xs
Line 1, characters 17-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val nlength : 'a list -> int = <fun>]]></html:pre>
            <html:p>These are two declarations, not one.  First we declare <html:code>nlength</html:code> to be a
function that handles only empty lists.  Then we redeclare it to be a function
that handles only non-empty lists; it can never deliver a result.  We see that
a second <html:code>let</html:code> declaration replaces any previous one rather than extending it
to cover new cases.</html:p>
            <html:p>Now, let us return to our original declaration of <html:code>nlength</html:code>.  The length function
is <html:em><fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link></html:em> and applies to <html:em>all</html:em> lists regardless of element
type!  Most programming languages lack such flexibility.</html:p>
            <html:p>Unfortunately, this length computation is naive and wasteful.  Like
<fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> earlier, it is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail-recursive</fr:link>.  It
uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its input.  As usual, the
solution is to add an accumulating argument.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/</fr:uri>
            <fr:display-uri>focs-length</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-length/</fr:route>
            <fr:title text="Efficiently Computing the Length of a List">Efficiently Computing the Length of a List</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec addlen n = function
  | []    -> n
  | x::xs -> addlen (n + 1) xs
val addlen : int -> 'a list -> int = <fun>
# addlen 0 [5; 6; 7]
- : int = 3]]></html:pre>
            <html:p>Recall that the use of <html:code>function</html:code> introduces an extra (unnamed) argument
that is <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matched</fr:link> in the subsequent clauses; in this case, to break
open the list.</html:p>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {addlen }0 [a; b; c] \Rightarrow  &\;  \text {addlen }1\;[b; c] \\
  \Rightarrow   &\; \text {addlen }2\;[c] \\
  \Rightarrow   &\; \text {addlen }3\;[] \\
  \Rightarrow   &\; 3
\end {aligned}
]]></fr:tex>
            <html:p>Function <html:code>addlen</html:code> is again <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.  Its type mentions the integer
accumulator.</html:p>
            <html:p>Now we may declare an efficient length function.  It is simply a wrapper for
<html:code>addlen</html:code>, supplying zero as the initial value of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
            <html:pre><![CDATA[# let length xs = addlen 0 xs
val length : 'a list -> int = <fun>
# length [5; 6; 7; 8]
- : int = 4]]></html:pre>
            <html:p>The recursive calls do not nest: this version is <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It takes <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
space.  Obviously its time requirement is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> because it takes at least <fr:tex display="inline"><![CDATA[n]]></fr:tex>
steps to find the length of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/</fr:uri>
            <fr:display-uri>focs-append</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-append/</fr:route>
            <fr:title text="Append: List Concatenation">Append: List Concatenation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec append xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> x :: append xs ys
val append : 'a list -> 'a list -> 'a list = <fun>
# append [1; 2; 3] [4]
- : int list = [1; 2; 3; 4]
# let (@) = append
val ( @ ) : 'a list -> 'a list -> 'a list = <fun>
# [1; 2; 3] @ [4]
- : int list = [1; 2; 3; 4]]]></html:pre>
            <html:p>Patterns can be as complicated as we like.  Here, the two patterns are
<html:code>[], ys</html:code> and <html:code>x::xs, ys</html:code>.</html:p>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {append }[1; 2; 3] [4] \Rightarrow  &\; 1 :: \text {append }[2; 3]\;[4] \\
  \Rightarrow  &\; 1 :: (2 :: \text {append }[3]\;[4]) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: \text {append }[]\;[4])) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: [4])) \ [1; 2; 3; 4]
\end {aligned}
]]></fr:tex>
            <html:p>Here is how append might be declared, also noting that we have defined <html:code>@</html:code> as
an infix operator that is a more convenient way to call <html:code>append</html:code> on two lists.
However, this function is also not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It scans its first
argument, sets up a string of <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code> operations</fr:link> (<html:code>::</html:code>) and finally does them.</html:p>
            <html:p>It uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its first argument.
<html:em>Its costs are independent of its second argument.</html:em></html:p>
            <html:p>An accumulating argument could make it iterative, but with considerable
complication.  The iterative version would still require <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time
because concatenation requires copying all the elements of the first list.
Therefore, we cannot hope for asymptotic gains; at best we can decrease the
constant factor involved in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>, but complicating the code is likely to
increase that factor.  Never add an accumulator merely out of habit.</html:p>
            <html:p>Note append’s <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic type</fr:link>. It tells us that two lists can be joined if
their element types agree.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nrev/</fr:uri>
            <fr:display-uri>focs-nrev</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-nrev/</fr:route>
            <fr:title text="Reversing a List in O(n^2)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Let us consider one way to reverse a list.</html:p>
            <html:pre><![CDATA[# let rec nrev = function
  | [] -> []
  | x::xs -> (nrev xs) @ [x]
val nrev : 'a list -> 'a list = <fun>
# nrev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nrev }[a; b; c] \Rightarrow  &\; \text {nrev }[b; c]\;@\;[a] \\
  \Rightarrow  &\;  (\text {nrev }[c]\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  ((\text {nrev }[]\;@\;[c])\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  (([]\;@\;[c])\;@\;[b])\;@\;[a] \ \ldots  \ [c; b; a]
\end {aligned}
]]></fr:tex>
            <html:p>This reverse function is grossly inefficient due to poor usage of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>, which
copies its first argument.  If <html:code>nrev</html:code> is given a list of length <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>, then
append makes <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> conses to copy the reversed tail.  Constructing the list
<html:code>[x]</html:code> calls <html:code>cons</html:code> again, for a total of <fr:tex display="inline"><![CDATA[n]]></fr:tex> calls.  Reversing the tail
requires <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> more conses, and so forth.  The total number of conses is:</html:p>
            <fr:tex display="block"><![CDATA[ 0 + 1 + 2 + \cdots  + n = {n(n+1)/2} ]]></fr:tex>
            <html:p>The time complexity is therefore <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Space complexity is only <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>
because the copies don’t all exist at the same time.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/</fr:uri>
            <fr:display-uri>focs-rev</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-rev/</fr:route>
            <fr:title text="Reversing a List in O(n)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec rev_app xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> rev_app xs (x::ys)
val rev_app : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {rev\_app }[a; b; c]\;[] \Rightarrow  &\; \text {rev\_app }[b; c]\; [a] \\
  \Rightarrow  &\; \text {rev\_app }[c]\; [b; a] \\
  \Rightarrow  &\; \text {rev\_app }[]\; [c; b; a] \\
  \Rightarrow  &\; [c; b; a]
\end {aligned}
]]></fr:tex>
            <html:p>Calling <html:code>rev_app xs ys</html:code> reverses the elements of <html:code>xs</html:code> and
prepends them to <html:code>ys</html:code>.  Now we may declare</html:p>
            <html:pre><![CDATA[# let rev xs = rev_app xs []
val rev : 'a list -> 'a list = <fun>
# rev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
            <html:p>It is easy to see that this reverse function performs just <fr:tex display="inline"><![CDATA[n]]></fr:tex> conses, given
an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.  For both reverse functions, we could count the number of
conses precisely—not just up to a constant factor.  <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> is still
useful to describe the overall running time: the time taken by a cons
varies from one system to another.</html:p>
            <html:p>The accumulator <fr:tex display="inline"><![CDATA[y]]></fr:tex> makes the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  But the gain in complexity
arises from the removal of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.  Replacing an expensive operation (append)
by a series of cheap operations (cons) is called <html:em>reduction in strength</html:em>
and is a common technique in computer science.  It originated when many
computers did not have a hardware multiply instruction; the series of products
<fr:tex display="inline"><![CDATA[i\times  r]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, <fr:tex display="inline"><![CDATA[\ldots , n]]></fr:tex> could more efficiently be computed by
repeated addition.  Reduction in strength can be done in various ways; we
shall see many instances of removing append.</html:p>
            <html:p>Consing to an accumulator produces the result in reverse.  If
that forces the use of an extra list reversal then the iterative function
may be much slower than the recursive one.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-strings-chars/</fr:uri>
            <fr:display-uri>focs-strings-chars</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-strings-chars/</fr:route>
            <fr:title text="Lists, Strings and Characters">Lists, Strings and Characters</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Strings are provided in most programming languages to allow text processing.
Strings are essential for communication with users. Even a purely numerical
program formats its results ultimately as strings.</html:p>
            <html:pre><![CDATA[# 'a'   (* a character constant *)
- : char = 'a'
# "a"   (* a string constant of length 1 *)
- : string = "a"
# "abc" (* a string constant of length 3 *)
- : string = "abc"
# String.length "abc"
- : int = 3
# "abc" ^ "def"  (* concatenate two strings *)
- : string = "abcdef"]]></html:pre>
            <html:p>In a few programming languages, strings simply are lists of characters. In
OCaml they are a separate type, unrelated to lists, reflecting the fact that
strings are an abstract concept in themselves.</html:p>
            <html:p>Similarly, characters are not strings of size one, but are a primitive concept.
Character constants in OCaml have the form <html:code>'c'</html:code>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is any character.
For example, the comma character is <html:code>','</html:code>.</html:p>
            <html:p>Special characters are coded in strings using <html:em>escape sequences</html:em> involving the
backslash character; among many others, a double quote is written <html:code><![CDATA["\\"]]></html:code> and
the newline character is written <html:code><![CDATA["\n"]]></html:code>. For example, the string
<html:code><![CDATA["I\nLIKE\nCHEESE\n"]]></html:code> represents three text lines.</html:p>
            <html:p>In addition to the operators described above, the relations <html:code>&lt;</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code>, and
<html:code>&gt;=</html:code> work for strings and yield alphabetic order (more precisely, lexicographic
order with respect to ASCII character codes).</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/</fr:uri>
            <fr:display-uri>focs-ex-3</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-3/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-1/</fr:uri>
                <fr:display-uri>focs-ex-3-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-1/</fr:route>
                <fr:title text="Summing a list">Summing a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function</fr:link> to compute the sum of a list’s elements. Then code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version
and comment on the improvement in efficiency.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-2/</fr:uri>
                <fr:display-uri>focs-ex-3-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-2/</fr:route>
                <fr:title text="Last element of a list">Last element of a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to return the last element of a non-empty list. How efficiently can this be done?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-3/</fr:uri>
                <fr:display-uri>focs-ex-3-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-3/</fr:route>
                <fr:title text="Even-numbered elements">Even-numbered elements</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to return the list consisting of the even-numbered elements of the list given as its
argument. For example, given <html:code>[a; b; c; d]</html:code> it should return <html:code>[b; d]</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-4/</fr:uri>
                <fr:display-uri>focs-ex-3-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-4/</fr:route>
                <fr:title text="Polymorphic types of id and loop">Polymorphic types of id and loop</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic types</fr:link> in these two function declarations:</html:p>
                <html:pre><![CDATA[# let id x = x
val id : 'a -> 'a = <fun>
# let rec loop x = loop x
val loop : 'a -> 'b = <fun>]]></html:pre>
                <html:p>Explain why these types make logical sense, preventing run time type errors, even for expressions
like <html:code>id [id [id 0]]</html:code> or <html:code>loop true / loop 3</html:code>. (<html:code>/</html:code> is the integer division operator in OCaml)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-5/</fr:uri>
                <fr:display-uri>focs-ex-3-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-5/</fr:route>
                <fr:title text="Tails of a list">Tails of a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function <html:code>tails</html:code> to return the list of the tails of its argument. For example, given
<html:code>[1; 2; 3]</html:code> it should return <html:code>[[1; 2; 3]; [2; 3]; [3]; []]</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/</fr:uri>
        <fr:display-uri>focs-more-lists</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-more-lists/</fr:route>
        <fr:title text="More on Lists">More on Lists</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/</fr:uri>
            <fr:display-uri>focs-take-drop</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-take-drop/</fr:route>
            <fr:title text="List Utilities: take and drop">List Utilities: take and drop</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>This lecture examines more list utilities, illustrating more patterns of
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, and concludes with a small program for <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.</html:p>
            <html:p>The functions <html:code>take</html:code> and <html:code>drop</html:code> divide a list
into parts, returning or discarding the first <fr:tex display="inline"><![CDATA[i]]></fr:tex> elements.</html:p>
            <fr:tex display="block"><![CDATA[xs = [\underbrace {x_0,\ldots ,x_{i-1}}_{\text {take i xs}},
      \underbrace {x_i,\ldots ,x_{n-1}}_{\text {drop i xs}} ]]]></fr:tex>
            <html:p>They can be implemented in OCaml as follows:</html:p>
            <html:pre><![CDATA[# let rec take i = function
    | [] -> []
    | x::xs ->
        if i > 0 then x :: take (i - 1) xs
        else []
val take : int -> 'a list -> 'a list = <fun>
# let rec drop i = function
    | [] -> []
    | x::xs ->
        if i > 0 then drop (i-1) xs
        else x::xs
val drop : int -> 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>Applications of <html:code>take</html:code> and <html:code>drop</html:code> will appear in future lectures.  Typically,
they divide a collection of items into equal parts for recursive processing.</html:p>
            <html:p>The <html:code>take</html:code> function is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>, but making it so would not improve
its efficiency.  The task requires copying up to <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements, which must
take <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> space and time.</html:p>
            <html:p>Function <html:code>drop</html:code> simply skips over <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements.  This requires
<fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time but only constant space.  It is iterative and much faster than
<html:code>take</html:code>.  Both functions use <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time, but skipping elements is faster
than copying them:  <html:code>drop</html:code>’s constant factor is smaller.</html:p>
            <html:p>Both functions take an integer and a list, returning a list of the same type.
So their type is <html:code>int -&gt; 'a list -&gt; 'a list</html:code>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/</fr:uri>
            <fr:display-uri>focs-linear-search</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-linear-search/</fr:route>
            <fr:title text="Linear Search">Linear Search</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>find <fr:tex display="inline"><![CDATA[x]]></fr:tex> in list <fr:tex display="inline"><![CDATA[[x_1,\ldots ,x_n]]]></fr:tex> by comparing with each element</html:li>
  <html:li>obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time</html:li>
  <html:li>simple &amp; general</html:li>
  <html:li>ordered searching needs only <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:li>
  <html:li>indexed lookup needs only <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
            <html:p><html:em>Linear search</html:em> is the obvious way to find a desired item in a
collection: simply look through all the items, one at a time.  If <fr:tex display="inline"><![CDATA[x]]></fr:tex> is in
the list, then it will be found in <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> steps on average, and even the worst
case is obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
            <html:p>Large collections of data are usually ordered or indexed so that items can be
found in <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> time, which is exponentially better than <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Even
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is achievable (using a hash table), though subject to the usual
proviso that machine limits are not exceeded.</html:p>
            <html:p>Efficient indexing methods are of prime importance: consider Web
search engines.  Nevertheless, linear search is often used to search small
collections because it is so simple and general, and it is the starting point
for better algorithms.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/</fr:uri>
            <fr:display-uri>focs-equality</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-equality/</fr:route>
            <fr:title text="Equality Tests">Equality Tests</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec member x = function
   | [] -> false
   | y::l ->
      if x = y then true
      else member x l
val member : 'a -> 'a list -> bool = <fun>]]></html:pre>
            <html:p>All the list functions we have encountered up to now have been “<fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>”,
working for lists of any type.  Function <html:code>member</html:code> uses <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link> to report
whether or not <html:code>x</html:code> occurs in <html:code>l</html:code>.</html:p>
            <html:p>To do this generically, it uses a special feature of OCaml known as
“polymorphic equality”, which manifests itself via the <html:code>=</html:code>, <html:code>&gt;=</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code> and
<html:code>&lt;</html:code> operators.  These operators inspect the <html:em>structure</html:em> of the values using a
consistent order.  Types you can legitimately compare this way include integers,
strings, booleans, and tuples or lists of primitive types.</html:p>
            <html:p>More complex types can be compared this way within careful limits: recursive
structures or function values will not work (we will cover function values in
the <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Currying lecture</fr:link> later).  For now, it is sufficient to use these magic
polymorphic equality operators.  As you get more familiar with OCaml and the
use of <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">higher order functions</fr:link> (also covered in a later lecture), you will
encounter the use of explicit <html:code>compare</html:code> functions that are used to provide more
complex equality tests.</html:p>
            <html:p>The presence of polymorphic equality is a contentious feature in OCaml.  While
it provides a great ease of use in smaller codebases, it starts to become more
dangerous when building larger OCaml-based systems.  Most large-scale users of
OCaml tend towards not using it in important code, but it is just fine for our
purposes while learning the beginning steps of computer science.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/</fr:uri>
            <fr:display-uri>focs-zip</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-zip/</fr:route>
            <fr:title text="Building a List of Pairs">Building a List of Pairs</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec zip xs ys =
    match xs, ys with
    | (x::xs, y::ys) -> (x, y) :: zip xs ys
    | _ -> []
val zip : 'a list -> 'b list -> ('a * 'b) list = <fun>]]></html:pre>
            <fr:tex display="block"><![CDATA[\left .[x_1,\ldots ,x_n]\atop 
         [y_1,\ldots ,y_n]\right \}\;\longmapsto \;[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex>
            <html:p>The <html:em>wildcard</html:em> pattern <html:code>_</html:code> matches <html:em>anything</html:em>. We could have written a
variable such as <html:code>p</html:code> instead, but the wildcard reminds us that the
relevant clause ignores this argument.</html:p>
            <html:p>The patterns are also tested in order of their definitions: first
<html:code>(x::xs, y::ys)</html:code>, then <html:code>_</html:code>.</html:p>
            <html:p>A list of pairs of the form <fr:tex display="inline"><![CDATA[[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex> associates each
<fr:tex display="inline"><![CDATA[x_i]]></fr:tex> with <fr:tex display="inline"><![CDATA[y_i]]></fr:tex>.  Conceptually, a telephone directory could be regarded as
such a list, where <fr:tex display="inline"><![CDATA[x_i]]></fr:tex> ranges over names and <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> over the corresponding
telephone number.  <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link> in such a list can find the <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> associated
with a given <fr:tex display="inline"><![CDATA[x_i]]></fr:tex>, or vice versa—very slowly.</html:p>
            <html:p>In other cases, the <fr:tex display="inline"><![CDATA[(x_i,y_i)]]></fr:tex> pairs might have been generated by applying a
function to the elements of another list <fr:tex display="inline"><![CDATA[[z_1,\ldots ,z_n]]]></fr:tex>.</html:p>
            <html:pre><![CDATA[# let rec unzip = function
   | [] -> ([], [])
   | (x, y)::pairs ->
       let xs, ys = unzip pairs in
       (x::xs, y::ys)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
            <html:p>Given a list of pairs, <html:code>unzip</html:code> has to build <html:em>two</html:em> lists of
results, which is awkward using recursion.  The version shown above uses the
<html:em>local binding</html:em> <html:code>let p = </html:code><fr:tex display="inline"><![CDATA[\;E_1\;]]></fr:tex><html:code> in </html:code><fr:tex display="inline"><![CDATA[\;E_2]]></fr:tex>,
where the value of <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> is bound to the variable <html:code>p</html:code> within <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>. The
let-construct counts as an expression and can be used (perhaps wrapped
within parentheses) wherever an expression is expected.</html:p>
            <html:p>Note especially the phrase <html:code>let xs, ys = unzip pairs</html:code>
which binds <html:code>xs</html:code> and <html:code>ys</html:code> to the results of the recursive call.
In general, the phrase <html:code>let P = E</html:code> matches the
pattern <fr:tex display="inline"><![CDATA[P]]></fr:tex> against the value of expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It binds all the variables
in <fr:tex display="inline"><![CDATA[P]]></fr:tex> to the corresponding values.</html:p>
            <html:p>The functions <html:code>zip</html:code> and <html:code>unzip</html:code> build and take apart lists of
pairs: <html:code>zip</html:code> pairs up corresponding list elements and <html:code>unzip</html:code>
inverts this operation.  Their types reflect what they do:</html:p>
            <html:pre><![CDATA[# zip
- : 'a list -> 'b list -> ('a * 'b) list = <fun>
# unzip
- : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
            <html:p>If the lists are of unequal length, <html:code>zip</html:code> discards surplus items at the
end of the longer list.  Its first pattern only matches a pair of non-empty
lists.  The second pattern is just a wildcard and could match anything.  OCaml
tries the clauses in the order given, so the first pattern is tried first.
The second only gets arguments where at least one of the lists is empty.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-unzip/</fr:uri>
            <fr:display-uri>focs-unzip</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-unzip/</fr:route>
            <fr:title text="Building a Pair of Results">Building a Pair of Results</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Here is a version of <html:code>unzip</html:code> that replaces the local declaration by a
function <html:code>conspair</html:code> for taking apart the pair of lists in the
recursive call.  It defines the same
computation as the previous version of <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local"><html:code>unzip</html:code></fr:link> and is possibly clearer,
but not every local binding can be eliminated as easily.</html:p>
            <html:pre><![CDATA[# let conspair ((x, y), (xs, ys)) = (x::xs, y::ys)
val conspair : ('a * 'b) * ('a list * 'b list) -> 'a list * 'b list = <fun>
# let rec unzip = function
    | [] -> ([], [])
    | xy :: pairs -> conspair (xy, unzip pairs)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
            <html:p>Making the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> yields <html:code>revUnzip</html:code> below, which is
very simple.  Iteration can construct many results at once in different
argument positions.  Both output lists are built in reverse order, which can
be corrected by reversing the input to <html:code>revUnzip</html:code>.  The total costs
will probably exceed those of <html:code>unzip</html:code> despite the advantages of
iteration.</html:p>
            <html:pre><![CDATA[# let rec revUnzip = function
    | ([], xs, ys) -> (xs, ys)
    | ((x, y)::pairs, xs, ys) ->
        revUnzip (pairs, x::xs, y::ys)
val revUnzip : ('a * 'b) list * 'a list * 'b list -> 'a list * 'b list =
  <fun>]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/</fr:uri>
            <fr:display-uri>focs-making-change</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-making-change/</fr:route>
            <fr:title text="An Application: Making Change">An Application: Making Change</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Consider a till that has unlimited supplies of coins.  The largest coins should be tried
first, to avoid giving change all in pennies.  The list of legal coin values,
called <html:code>till</html:code>, is given in descending order, such as 50, 20, 10, 5,
2 and 1.  (Recall that the <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">head of a list</fr:link> is the element most easily reached.)
The code for <html:code>change</html:code> is based on simple observations:</html:p>
            <html:ul><html:li>Change for zero consists of no coins at all.  (Note the pattern of <html:code>0</html:code> in the first clause.)</html:li>
  <html:li>For a nonzero amount, try the largest available coin.  If it is small enough, use it and decrease the amount accordingly.</html:li>
  <html:li>Exclude from consideration any coins that are too large.</html:li></html:ul>
            <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise (Failure "no more coins!")
    | c::till, amt -> if amt < c then change till amt
                      else c :: change (c::till) (amt - c)
val change : int list -> int -> int list = <fun>]]></html:pre>
            <html:p>Although nobody considers making change for zero, this is the simplest way to
make the algorithm terminate.  Most iterative procedures become simplest if,
in their base case, they do nothing.  A base case of one instead of zero is
often a sign of a novice programmer.</html:p>
            <html:ul><html:li>The <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> <html:em>terminates</html:em> when <html:code>amt = 0</html:code>.</html:li>
  <html:li>Tries the <html:em>largest coin first</html:em> to use large coins.</html:li>
  <html:li>The algorithm is <html:em>greedy</html:em> and can fail!</html:li></html:ul>
            <html:p>The function can terminate either with success or failure.  It fails by
raising exception <html:code>Failure</html:code> namely if <html:code>till</html:code> becomes empty while <html:code>amt</html:code> is still nonzero.
(<fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">Exceptions</fr:link> will be discussed later.)</html:p>
            <html:p>Unfortunately, failure can occur even when change can be made.  The greedy
"largest coin first" approach is to blame.  Suppose we have coins of values 5
and 2, and must make change for 6; the only way is <fr:tex display="inline"><![CDATA[6=2+2+2]]></fr:tex>, ignoring the 5.
<html:em>Greedy algorithms</html:em> are often effective, but not here.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/</fr:uri>
            <fr:display-uri>focs-change-all</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-change-all/</fr:route>
            <fr:title text="All Ways of Making Change">All Ways of Making Change</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Now we generalise the problem to return the list of <html:em>all possible ways</html:em> of making change,
and write a new <html:code>change</html:code> function.</html:p>
            <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
            <html:p>Look at the type: the result is now a list of lists.
The code will also never raise <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>.  It expresses failure by returning an
empty list of solutions: it returns <html:code>[]</html:code> if the till is empty and the
amount is nonzero.</html:p>
            <html:p>If the amount is zero, then there is only one way of making change;
the result should be <html:code><![CDATA[[[]]]]></html:code>.  This is success in the base case.</html:p>
            <html:p>In nontrivial cases, there are two sources of solutions: to use a coin (if
possible) and decrease the amount accordingly, or to remove the current coin
value from consideration.</html:p>
            <html:p>The function <html:code>allc</html:code> is declared locally in order to make use
of <html:code>c</html:code>, the current coin.  It adds an extra <html:code>c</html:code> to all the
solutions returned by the recursive call to make change for <html:code>amt - c</html:code>.</html:p>
            <html:p>Observe the naming convention: <html:code>cs</html:code> is a list of coins, while
<html:code>css</html:code> is a list of such lists.  The trailing ‘s’ is suggestive of a
plural.</html:p>
            <html:p>This complicated program, and the even trickier one on the next slide, are
included as challenges.  Are you enthusiastic enough to work them out?  We
shall revisit the “making change” task later to illustrate <fr:link href="/~avsm2/fcs/focs-change-exceptions/" title="Making Change with Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/" display-uri="focs-change-exceptions" type="local">exception-handling</fr:link>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-faster/</fr:uri>
            <fr:display-uri>focs-change-faster</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-change-faster/</fr:route>
            <fr:title text="All Ways of Making Change — Faster!">All Ways of Making Change — Faster!</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec change till amt chg chgs =
    match till, amt with
    | _       , 0   -> chg::chgs
    | []      , _   -> chgs
    | c::till , amt -> if amt < 0 then chgs
                       else change (c::till) (amt - c) (c::chg)
                                   (change till amt chg chgs)
val change : int list -> int -> int list -> int list list -> int list list =
  <fun>]]></html:pre>
            <html:p>We’ve added <html:em>another</html:em> accumulating parameter!  Repeatedly improving simple code
is called <html:em>stepwise refinement</html:em>.</html:p>
            <html:p>Two extra arguments eliminate many <html:code>::</html:code> and append operations from the previous
slide’s <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local"><html:code>change</html:code></fr:link> function.  The first, <html:code>chg</html:code>, accumulates the coins chosen so
far; one evaluation of <html:code>c::chg</html:code> replaces many evaluations of <html:code>allc</html:code>.  The
second, <html:code>chgs</html:code>, accumulates the list of solutions so far; it avoids the need
for <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link>.  This version runs several times faster than the previous one.</html:p>
            <html:p>Making change is still extremely slow for an obvious reason: the number of
solutions grows rapidly in the amount being changed.  Using 50, 20, 10, 5,
2 and 1, there are 4366 ways of expressing 99.</html:p>
            <html:p>Our three change functions illustrate a basic technique: program development
by stepwise refinement.  Begin by writing a very simple program and add
requirements individually.  Add efficiency refinements last of all.
Even if the simpler program cannot be included in the next version and has
to be discarded, one has learned about the task by writing it.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/</fr:uri>
            <fr:display-uri>focs-ex-4</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-4/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-1/</fr:uri>
                <fr:display-uri>focs-ex-4-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-1/</fr:route>
                <fr:title text="Set union without repetitions">Set union without repetitions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Sets can be represented in OCaml using lists containing no duplicated items
(i.e. where no item is equal to another using <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link> comparison).</html:p>
                <html:p>Using the <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link> function defined above, code a function to implement set
union. It should avoid introducing repetitions, for example the union of the
lists <html:code>[4; 7; 1]</html:code> and <html:code>[6; 4; 7]</html:code> should be <html:code>[1; 6; 4; 7]</html:code> (though the order
does not matter).</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-2/</fr:uri>
                <fr:display-uri>focs-ex-4-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-2/</fr:route>
                <fr:title text="Partitioning integers by sign">Partitioning integers by sign</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function that takes a list of integers and returns two lists, the first consisting of all
non-negative numbers found in the input and the second consisting of all the negative numbers.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-3/</fr:uri>
                <fr:display-uri>focs-ex-4-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-3/</fr:route>
                <fr:title text="A non-exhaustive zip">A non-exhaustive zip</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>How does this version of <html:code>zip</html:code> differ from <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local">the one above</fr:link>?</html:p>
                <html:pre><![CDATA[let rec zip xs ys =
  match xs, ys with
  | (x::xs, y::ys) -> (x, y) :: zip xs ys
  | ([], [])   -> []]]></html:pre>
                <html:pre><![CDATA[Lines 2-4, characters 5-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(_::_, [])]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-4/</fr:uri>
                <fr:display-uri>focs-ex-4-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-4/</fr:route>
                <fr:title text="Assumptions in making change">Assumptions in making change</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What assumptions do the <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">‘making change’</fr:link> functions make about the variables <html:code>till</html:code> and <html:code>amt</html:code>?
Describe what could happen if these assumptions were violated.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-5/</fr:uri>
                <fr:display-uri>focs-ex-4-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-5/</fr:route>
                <fr:title text="Counting ways of making change">Counting ways of making change</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the number of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">ways of making change</fr:link> for <fr:tex display="inline"><![CDATA[n]]></fr:tex> (ignoring order) is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> if there are two
legal coin values. What if there are three, four, … coin values?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-6/</fr:uri>
                <fr:display-uri>focs-ex-4-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-6/</fr:route>
                <fr:title text="Reasoning from polymorphic types">Reasoning from polymorphic types</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>We know nothing about the functions <html:code>f</html:code> and <html:code>g</html:code> other than their polymorphic types:
<html:code>val f : 'a * 'b -&gt; 'b * 'a</html:code> and <html:code>val g : 'a -&gt; 'a list</html:code>.
Suppose that <html:code>f (1, true)</html:code> and <html:code>g 0</html:code> are evaluated and return their results. State, with reasons,
what you think the resulting values will be.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/</fr:uri>
        <fr:display-uri>focs-sorting</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-sorting/</fr:route>
        <fr:title text="Sorting">Sorting</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>A few applications for sorting and arranging items into order are:</html:p>
        <html:ul><html:li>search</html:li>
  <html:li>merging</html:li>
  <html:li>duplicates</html:li>
  <html:li>inverting tables</html:li>
  <html:li>graphics algorithms</html:li></html:ul>
        <html:p>Sorting is perhaps the most deeply studied aspect of algorithm design.
Knuth’s series <html:em>The Art of Computer Programming</html:em> devotes an entire
volume to sorting and searching!  <fr:link href="https://algs4.cs.princeton.edu/home/" type="external">Sedgewick</fr:link>
also covers sorting.  Sorting has countless applications.</html:p>
        <html:p>Sorting a collection allows items to be found quickly.  Recall that <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear
search</fr:link> requires <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> steps to search among <fr:tex display="inline"><![CDATA[n]]></fr:tex> items.  A sorted collection
admits <html:em>binary search</html:em> which requires only <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> time.  The idea
of binary search is to compare the item being sought with the middle item (in
position <fr:tex display="inline"><![CDATA[n/2]]></fr:tex>) and then to discard either the left half or the right,
depending on the result of the comparison.  Binary search needs arrays or
trees, not lists; we shall come to <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link> later.</html:p>
        <html:p>Two sorted files can quickly be <html:em>merged</html:em> to form a larger sorted file.  Other
applications include finding <html:em>duplicates</html:em> that, after sorting, are adjacent.</html:p>
        <html:p>A telephone directory is sorted alphabetically by name.  The same information
can instead be sorted by telephone number (useful to the police) or by street
address (useful to junk-mail firms).  Sorting information in different ways
gives it different applications.</html:p>
        <html:p>Common sorting algorithms include insertion sort, quicksort,
mergesort and heapsort.  We shall consider the first three of
these.  Each algorithm has its advantages.</html:p>
        <html:p>As a concrete basis for comparison, runtimes are quoted for DECstation
computers.  These were based on the MIPS chip (an early RISC design)
and are really old now, but still useful to look at relative to each other.</html:p>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-bounds/</fr:uri>
            <fr:display-uri>focs-sorting-bounds</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-sorting-bounds/</fr:route>
            <fr:title text="How Fast Can We Sort?">How Fast Can We Sort?</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>typically count <html:em>comparisons</html:em> <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex></html:li>
  <html:li>there are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements</html:li>
  <html:li>each comparison eliminates <html:em>half</html:em> of the permutations <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex></html:li>
  <html:li>therefore <fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex></html:li></html:ul>
            <html:p>The usual measure of efficiency for sorting algorithms is the number of
comparison operations required.  <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link> requires only <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>
comparisons to sort an input of <fr:tex display="inline"><![CDATA[n]]></fr:tex> items.  It is straightforward to prove
that this complexity is the best possible.  There
are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements and each comparison distinguishes two
permutations.  The lower bound on the number of comparisons, <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex>, is
obtained by solving <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex>; therefore
<fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex>.</html:p>
            <html:p>In order to compare the sorting algorithms, we use the <fr:link href="http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf" type="external">following source</fr:link> of
pseudo-random numbers. Never mind how this works: generating
statistically good random numbers is hard.  Much effort has gone into those few
lines of code.</html:p>
            <html:pre><![CDATA[# let nextrandom seed =
    let a = 16807.0 in
    let m = 2147483647.0 in
    let t = a *. seed in
    t -. m *. (floor (t /. m))
val nextrandom : float -> float = <fun>
# let rec randlist (seed, seeds) = function
    | 0 -> (seed, seeds)
    | n -> randlist (nextrandom seed, seed::seeds) (n-1)
val randlist : float * float list -> int -> float * float list = <fun>]]></html:pre>
            <html:p>We can now bind the identifier <html:code>rs</html:code> to a list of 10,000 random numbers.</html:p>
            <html:pre><![CDATA[# let seed, rs = randlist (1.0, []) 10000
val seed : float = 1043618065.
val rs : float list =
  [1484786315.; 925166085.; 1614852353.; 721631166.; 173942219.; 1229443779.;
   789328014.; 570809709.; 1760109362.; 270600523.; 2108528931.; 16480421.;
   519782231.; 162430624.; 372212905.; 1954184989.; 898872741.; 1651521688.;
   1114791388.; 1325968501.; 1469981427.; 465437343.; 1732504088.;
   280054095.; 1924919450.; 1244369648.; 1524535715.; 706293012.;
   1372325856.; 1302473561.; 941382430.; 2137445578.; 1937168414.;
   1852570660.; 495231255.; 1092873378.; 140232191.; 328129841.; 632752255.;
   227857208.; 1616471915.; 719842438.; 1402481130.; 745001020.; 791471334.;
   2131048000.; 312659966.; 1389551813.; 443838892.; 854190041.; 741774068.;
   267473377.; 1372555293.; 1539748349.; 697860888.; 1261546017.; 734770781.;
   1512111397.; 813238415.; 1034499961.; 602256496.; 462191385.; 250718457.;
   246489360.; 295426232.; 468306241.; 877829533.; 1130589227.; 1914364883.;
   1479854970.; 878528585.; 1268712064.; 115837978.; 1803525169.; 689954646.;
   1174020926.; 651968560.; 391152461.; 1776325865.; 2015344107.; 246977673.;
   1381242649.; 1115030853.; 190703911.; 316761032.; 464218769.; 1537522160.;
   1958981931.; 390463588.; 224009597.; 235243732.; 620352731.; 1374109567.;
   832140633.; 675075162.; 1296171190.; 2009054653.; 1534419747.; 145880482.;
   1649432515.; 403989126.; 1112417244.; 1290575192.; 896661113.; 218545469.;
   1002393512.; 2131316096.; 551979127.; 932010335.; 665881436.; 1975412808.;
   639877791.; 1781707137.; 894518191.; 568004958.; 1331430214.; 629489848.;
   183264178.; 162027282.; 464592882.; 93302056.; 1178713033.; 1401486247.;
   1846150129.; 1646978216.; 1104441491.; 111995009.; 66193165.; 2038880392.;
   79340676.; 871801051.; 967550305.; 2067810758.; 1600354198.; 1746626663.;
   1516388116.; 1308870791.; 173082747.; 189881227.; 478010722.; 739707315.;
   255334803.; 164203714.; 1893097038.; 1587694259.; 292950569.; 918323194.;
   41453146.; 1217297445.; 256768724.; 586494122.; 586258194.; 660494391.;
   507554325.; 699716071.; 672895139.; 76065072.; 1594869218.; 1439459639.;
   641123634.; 1650611940.; 177447368.; 301427463.; 525804524.; 553672425.;
   926899509.; 794676486.; 690277940.; 2115070333.; 1062048650.; 1653192448.;
   1808855340.; 126475289.; 1028198214.; 1739565096.; 1515748830.;
   427491435.; 319330584.; 666483848.; 854842154.; 1853528448.; 1975611245.;
   1905343266.; 1229802342.; 1416055428.; 2091603253.; 1068308139.;
   198239748.; 982076370.; 1094563396.; 44402415.; 889814989.; 290736902.;
   417580014.; 1935788352.; 595665917.; 367638848.; 894945148.; 1868608068.;
   317883051.; 941451621.; 1595942893.; 789094274.; 1150772108.; 422742112.;
   1444245279.; 1273601104.; 256005435.; 1742330161.; 1514599036.;
   956344512.; 2113041793.; 293237373.; 1386995194.; 1509339194.; 891946522.;
   1020832915.; 592544922.; 1746311153.; 1471539715.; 143832370.;
   2041568248.; 1039556199.; 1608726047.; 1205124472.; 2123533995.;
   1560620058.; 1837598795.; 1028172251.; 98318742.; 1405510706.;
   1047695837.; 59221314.; 1822176683.; 1096018886.; 1528104537.;
   1270922857.; 812074106.; 291115596.; 795788616.; 638657646.; 2034314619.;
   1527649272.; 156357479.; 1010056202.; 1139413443.; 1110927723.;
   1216083346.; 846825145.; 2100385733.; 315213605.; 1629637749.;
   1139833627.; 895118866.; 296359237.; 1361440746.; 1188627020.;
   1964199872.; 166733080.; 54185744.; 575493576.; 1810324496.; 1765549585.;
   53514233.; 747348448.; 61758907.; 1710119765.; 188311628.; 8827553.;
   67975851.; 1808633248.; 1290488843.; 1264775607.; 1711469075.;
   1537468597.; 706677101.; 518290019.; 190285086.; 157683412.; 985907152.;
   1571668636.; 632570698.; 791081325.; 1773794197.; 1787141077.;
   1727982894.; 794213057.; 633163306.; 682601940.; 1573439414.; 1041956036.;
   1169697582.; 758914445.; 2096291761.; 1502226099.; 1665995955.;
   948048264.; 1596326605.; 1816773893.; ...]]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/</fr:uri>
            <fr:display-uri>focs-insertion-sort</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-insertion-sort/</fr:route>
            <fr:title text="Insertion Sort">Insertion Sort</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>An insert operation does <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> comparisons on average.</html:p>
            <html:pre><![CDATA[# let rec ins x = function
    | [] -> [x]
    | y::ys -> if x <= y then x :: y :: ys
               else y :: ins x ys
val ins : 'a -> 'a list -> 'a list = <fun>]]></html:pre>
            <html:p><html:em>Insertion sort</html:em> takes <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons on average:</html:p>
            <html:pre><![CDATA[let rec insort = function
    | [] -> []
    | x::xs -> ins x (insort xs)]]></html:pre>
            <html:p>Items from the input are copied one at a time to the output.  Each new item is
inserted into the right place so that the output is always in order.</html:p>
            <html:p>We could easily write <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> versions of these functions, but to no purpose.
Insertion sort is slow because it does <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons (and a lot of list
copying), not because it is recursive.  Its quadratic runtime makes it nearly
useless: it takes 174 seconds for our example while the next-worst figure is
1.4 seconds.</html:p>
            <html:p>Insertion sort is worth considering because it is easy to code and illustrates
the concepts.  Two efficient sorting algorithms, <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link> and heapsort, can be
regarded as refinements of insertion sort.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/</fr:uri>
            <fr:display-uri>focs-quicksort-idea</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-quicksort-idea/</fr:route>
            <fr:title text="Quicksort: The Idea">Quicksort: The Idea</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>The Quicksort algorithm has the following flow:</html:p>
            <html:ul><html:li>Choose a <html:em>pivot</html:em> element, <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li>
  <html:li>Divide to partition the input into two sublists:
    <html:ul><html:li>those <html:em>at most</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex> in value</html:li>
      <html:li>those <html:em>exceeding</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li></html:ul></html:li>
  <html:li>Conquer using recursive calls to sort the sublists</html:li>
  <html:li>Combine the sorted lists by appending one to the other</html:li></html:ul>
            <html:p>Quicksort was invented by Sir Anthony Hoare, who works at Microsoft Research,
Cambridge.  Quicksort works by <html:em>divide and conquer,</html:em> a basic algorithm design
principle.  Quicksort chooses from the input some value <fr:tex display="inline"><![CDATA[a]]></fr:tex>, called the
<html:em>pivot</html:em>.  It partitions the remaining items into two parts: those <fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>, and
those <fr:tex display="inline"><![CDATA[>a]]></fr:tex>.  It sorts each part recursively, then puts the smaller part before
the greater.</html:p>
            <html:p>The cleverest feature of Hoare's algorithm was that the partition could be done
<html:em>in place</html:em> by exchanging array elements.  Quicksort was invented before
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> was well known, and people found it extremely hard to understand.  As
usual, we shall consider a list version based on functional programming.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/</fr:uri>
            <fr:display-uri>focs-quicksort</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-quicksort/</fr:route>
            <fr:title text="Quicksort: The Code">Quicksort: The Code</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec quick = function
    | [] -> []
    | [x] -> [x]
    | a::bs ->
        let rec part l r = function
          | [] -> (quick l) @ (a :: quick r)
          | x::xs ->
              if (x <= a) then
                part (x::l) r xs
              else
                part l (x::r) xs
        in
        part [] [] bs
val quick : 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>Our OCaml quicksort copies the items.  It is still pretty fast, and it is much
easier to understand.  It takes roughly 0.74 seconds to sort our list of random
numbers.</html:p>
            <html:p>The function declaration consists of three clauses.  The first handles the
empty list; the second handles singleton lists (those of the form <html:code>[x]</html:code>); the
third handles lists of two or more elements.  Often, lists of length up to five
or so are treated as special cases to boost speed.</html:p>
            <html:p>The locally declared function <html:code>part</html:code> partitions the input using <html:code>a</html:code> as the
pivot.  The arguments <html:code>l</html:code> and <html:code>r</html:code> accumulate items for the left (<fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>) and
right (<fr:tex display="inline"><![CDATA[>a]]></fr:tex>) parts of the input, respectively.</html:p>
            <html:p>It is not hard to prove that quicksort does <fr:tex display="inline"><![CDATA[n\log  n]]></fr:tex> comparisons, <html:em>in the average case</html:em>
(see <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">page 94 of Aho</fr:link>).  With random data, the pivot
usually has an average value that divides the input in two approximately equal
parts.  We have the recurrence <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>, which is
<fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.  In our example, it is about 235 times faster than <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insertion
sort</fr:link>.</html:p>
            <html:p>In the worst case, quicksort's running time is quadratic!  An example is when
its input is almost sorted or reverse sorted.  Nearly all of the items end up
in one partition; work is not divided evenly.  We have the recurrence
<fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>, which is <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Randomising the input
makes the worst case highly unlikely.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-append-free/</fr:uri>
            <fr:display-uri>focs-quicksort-append-free</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-quicksort-append-free/</fr:route>
            <fr:title text="Append-Free Quicksort">Append-Free Quicksort</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec quik = function
    | ([], sorted) -> sorted
    | ([x], sorted) -> x::sorted
    | a::bs, sorted ->
       let rec part = function
         | l, r, [] -> quik (l, a :: quik (r, sorted))
         | l, r, x::xs ->
             if x <= a then
               part (x::l, r, xs)
             else
               part (l, x::r, xs)
       in
       part ([], [], bs)
val quik : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>The list <html:code>sorted</html:code> accumulates the result in the <html:em>combine</html:em> stage of
the quicksort algorithm.  We have again used the standard technique for
<fr:link href="/~avsm2/fcs/focs-rev/" title="Reversing a List in O(n)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/" display-uri="focs-rev" type="local">eliminating append</fr:link>.  Calling <html:code>quik(xs, sorted)</html:code> reverses the elements of
<html:code>xs</html:code> and prepends them to the list <html:code>sorted</html:code>.</html:p>
            <html:p>Looking closely at <html:code>part</html:code>, observe that <html:code>quik(r, sorted)</html:code> is
performed first.  Then <html:code>a</html:code> is consed to this sorted list.  Finally,
<html:code>quik</html:code> is called again to sort the elements of <html:code>l</html:code>.</html:p>
            <html:p>The speedup is significant.  An imperative quicksort coded in Pascal (taken
from <fr:link href="https://algs4.cs.princeton.edu/20sorting/" type="external">Sedgewick</fr:link>) is just slightly faster than function
<html:code>quik</html:code>.  The near-agreement is surprising because the computational overheads
of lists exceed those of arrays.  In realistic applications, comparisons are
the dominant cost and the overheads matter even less.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge/</fr:uri>
            <fr:display-uri>focs-merge</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-merge/</fr:route>
            <fr:title text="Merging Two Lists">Merging Two Lists</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Merge joins two sorted lists.</html:p>
            <html:pre><![CDATA[# let rec merge = function
    | [], ys -> ys
    | xs, [] -> xs
    | x::xs, y::ys ->
        if x <= y then
          x :: merge (xs, y::ys)
        else
          y :: merge (x::xs, ys)
val merge : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>Generalises <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insert</fr:link> to two lists, and does at most <fr:tex display="inline"><![CDATA[m+n-1]]></fr:tex> comparisons.</html:p>
            <html:p><html:em>Merging</html:em> means combining two sorted lists to form a larger sorted list.
It does at most <fr:tex display="inline"><![CDATA[m+n]]></fr:tex> comparisons, where <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are the lengths of the
input lists.  If <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are roughly equal then we have a fast way of
constructing sorted lists; if <fr:tex display="inline"><![CDATA[n=1]]></fr:tex> then merging degenerates to insertion,
doing much work for little gain.</html:p>
            <html:p>Merging is the basis of several sorting algorithms; we look at a
divide-and-conquer one.  Mergesort is seldom found in conventional programming
because it is hard to code for arrays; it works nicely with lists.  It divides
the input (if non-trivial) into two roughly equal parts, sorts them
recursively, then merges them.</html:p>
            <html:p>Function <html:code>merge</html:code> is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>; the recursion is deep.  An iterative
version is of little benefit for the same reasons that apply to
<fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link> in the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">earlier lecture on Lists</fr:link>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/</fr:uri>
            <fr:display-uri>focs-merge-sort</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-merge-sort/</fr:route>
            <fr:title text="Top-down Merge sort">Top-down Merge sort</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec tmergesort = function
    | [] -> []
    | [x] -> [x]
    | xs ->
        let k = List.length xs / 2 in
        let l = tmergesort (take k xs) in
        let r = tmergesort (drop k xs) in
        merge (l, r)
val tmergesort : 'a list -> 'a list = <fun>]]></html:pre>
            <html:p><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons in worst case</html:p>
            <html:p>Mergesort’s <html:em>divide</html:em> stage divides the input not by choosing a pivot (as
in <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>) but by simply counting out half of the elements.  The
<html:em>conquer</html:em> stage again involves recursive calls, and the <html:em>combine</html:em>
stage involves merging.  Function <html:code>tmergesort</html:code> takes roughly 1.4
seconds to sort the list <html:code>rs</html:code>.</html:p>
            <html:p>In the worst case, mergesort does <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons, with the same
recurrence equation as in quicksort’s average case.  Because <fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>take</html:code></fr:link> and
<fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>drop</html:code></fr:link> divide the input in two equal parts (they differ at most by
one element), we always have <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>.</html:p>
            <html:p>Quicksort is nearly 3 times as fast in the example.  But it risks a
quadratic worst case!  Merge sort is safe but slow.  So which algorithm is
best?</html:p>
            <html:p>We have seen a <html:em>top-down</html:em> mergesort.  <html:em>Bottom-up</html:em> algorithms also
exist.  They start with a list of one-element lists and repeatedly merge
adjacent lists until only one is left.  A refinement, which exploits any
initial order among the input, is to start with a list of increasing or
decreasing runs of input items.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-summary/</fr:uri>
            <fr:display-uri>focs-sorting-summary</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-sorting-summary/</fr:route>
            <fr:title text="Summary of Sorting Algorithms">Summary of Sorting Algorithms</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Optimal is <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">Insertion sort</fr:link>: simple to code; too slow (quadratic) [174 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-quicksort/" title="Quicksort: The Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/" display-uri="focs-quicksort" type="local">Quicksort</fr:link>: fast on average; quadratic in worst case [0.53 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link>: optimal in theory; often slower than quicksort [1.4 secs]</html:li>
  <html:li><html:em>Match the algorithm to the application</html:em></html:li></html:ul>
            <html:p>Quicksort’s worst case cannot be ignored.  For large <fr:tex display="inline"><![CDATA[n]]></fr:tex>, a complexity of
<fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> is catastrophic.  Mergesort has an <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> worst case running
time, which is optimal, but it is typically slower than quicksort for random
data.</html:p>
            <html:p>Non-comparison sorting deserves mentioning.  We can sort a large number of
small integers using their radix representation in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time.  This result
does not contradict the comparison-counting argument because comparisons are
not used at all.  Linear time is achievable only if the greatest integer is
fixed in advance; as <fr:tex display="inline"><![CDATA[n]]></fr:tex> goes to infinity, increasingly many of the items
are the same.  It is a simple special case.</html:p>
            <html:p>Many other sorting algorithms exist. A few are outlined in <fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">the exercises</fr:link>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/</fr:uri>
            <fr:display-uri>focs-ex-5</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-5/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-1/</fr:uri>
                <fr:display-uri>focs-ex-5-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-1/</fr:route>
                <fr:title text="Complexity of selection sort">Complexity of selection sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another sorting algorithm (selection sort) consists of looking at the elements to be sorted,
identifying and removing a minimal element, which is placed at the head of the result. The tail is
obtained by recursively sorting the remaining elements. State, with justification, the time
complexity of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-2/</fr:uri>
                <fr:display-uri>focs-ex-5-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-2/</fr:route>
                <fr:title text="Implementing selection sort">Implementing selection sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Implement selection sort (see previous exercise) using OCaml.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-3/</fr:uri>
                <fr:display-uri>focs-ex-5-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-3/</fr:route>
                <fr:title text="Complexity of bubble sort">Complexity of bubble sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another sorting algorithm (bubble sort) consists of looking at adjacent pairs of elements,
exchanging them if they are out of order and repeating this process until no more exchanges are
possible. State, with justification, the time complexity of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-4/</fr:uri>
                <fr:display-uri>focs-ex-5-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-4/</fr:route>
                <fr:title text="Implementing bubble sort">Implementing bubble sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Implement bubble sort (see previous exercise) using OCaml.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-datatypes/</fr:uri>
        <fr:display-uri>focs-datatypes</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-datatypes/</fr:route>
        <fr:title text="Datatypes and Trees">Datatypes and Trees</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-enumeration/</fr:uri>
            <fr:display-uri>focs-enumeration</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-enumeration/</fr:route>
            <fr:title text="An Enumeration Type">An Enumeration Type</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>We will now learn how to define more expressive types than the
basic ones supplied with the core OCaml language.</html:p>
            <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike
               | Car
               | Lorry
type vehicle = Bike | Motorbike | Car | Lorry]]></html:pre>
            <html:ul><html:li>We have declared a <html:em>new type</html:em> named <html:code>vehicle</html:code>.</html:li>
  <html:li><fr:tex display="inline"><![CDATA[\ldots ]]></fr:tex> along with four new constants.</html:li>
  <html:li>They are the <html:em>constructors</html:em> of the <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>.</html:li></html:ul>
            <html:p>The <html:code>type</html:code> declaration adds a new type to our OCaml session.  Type
<html:code>vehicle</html:code> is as good as any built-in type and even admits
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> (as we used with the <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">built-in list types</fr:link> earlier).
The four new identifiers of type <html:code>vehicle</html:code> are called <html:em>constructors</html:em>.</html:p>
            <html:p>We could represent the various vehicles by the numbers 0–3.  However, the code would be
hard to read and even harder to maintain.  Consider adding <html:code>Tricycle</html:code>
as a new vehicle. If we wanted to add it before <html:code>Bike</html:code>, then all the
numbers would have to be changed.  Using <html:code>type</html:code>, such additions are
trivial and the compiler can (at least sometimes) warn us when it encounters a
function declaration that doesn’t yet have a case for <html:code>Tricycle</html:code>.</html:p>
            <html:p>Representing vehicles by strings like <html:code>"Bike"</html:code>, <html:code>"Car"</html:code>, etc.,
is also bad.  Comparing string values is slow and the compiler
can’t warn us of misspellings like <html:code>"MOtorbike"</html:code>: they will make our
code fail.</html:p>
            <html:p>Most programming languages allow the declaration of types like
<html:code>vehicle</html:code>.  Because they consist of a series of identifiers, they are
called <html:em>enumeration types</html:em>.  Other common examples are days of the week
or colours.  The compiler chooses the integers for us; type-checking prevents
us from confusing <html:code>Bike</html:code> with <html:code>Red</html:code> or <html:code>Sunday</html:code>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-vehicles/</fr:uri>
            <fr:display-uri>focs-vehicles</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-vehicles/</fr:route>
            <fr:title text="Declaring a Function on Vehicles">Declaring a Function on Vehicles</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let wheels = function
  | Bike -> 2
  | Motorbike -> 2
  | Car -> 4
  | Lorry -> 18
val wheels : vehicle -> int = <fun>]]></html:pre>
            <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">Datatype constructors</fr:link> can be used in patterns.</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">Pattern-matching</fr:link> is fast, even complicated nested patterns.</html:li>
  <html:li>Notice the type of the argument is <html:code>vehicle</html:code>, which we defined earlier.</html:li></html:ul>
            <html:p>The beauty of datatype declarations is that the new types behave as if they
were built into OCaml. Type-checking catches common errors, such as mixing up
different datatypes in a function like <html:code>wheels</html:code>, as well as missing
and redundant patterns.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/</fr:uri>
            <fr:display-uri>focs-constructors-args</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-constructors-args/</fr:route>
            <fr:title text="A Datatype whose Constructors have Arguments">A Datatype whose Constructors have Arguments</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int
               | Car       of bool
               | Lorry     of int
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
            <html:ul><html:li>Constructors with arguments (like <html:code>Lorry</html:code>) are <html:em>distinct values</html:em>. (So <html:code>Car true</html:code> is distinct from <html:code>Car false</html:code>).</html:li>
  <html:li>Different kinds of <html:code>vehicle</html:code> can belong to one list: <html:code>[Bike, Car true, Motorbike 450]</html:code></html:li></html:ul>
            <html:p>OCaml generalises the notion of enumeration type to allow data to be associated
with each constructor.  The constructor <html:code>Bike</html:code> is a vehicle all by itself, but
the other three constructors create vehicles from arguments.</html:p>
            <html:p>Since we might find it hard to remember what the various <html:code>int</html:code> and
<html:code>bool</html:code> components are for, it is wise to include <html:em>comments</html:em> in
complex declarations.  In OCaml, comments are enclosed in the brackets
<html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>. Programmers should comment their code to explain
design decisions and key features of the algorithms (sometimes by citing a
reference work).</html:p>
            <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int  (* engine size in CCs *)
               | Car       of bool (* true if a Reliant Robin *)
               | Lorry     of int  (* number of wheels *)
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
            <html:p>The list shown on the slide represents a bicycle, a Reliant Robin and a large
motorbike.  It can be almost seen as a mixed-type list containing integers and
booleans.  It is actually a list of vehicles; datatypes lessen the impact of
the restriction that all list elements must have the same type.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-wheels/</fr:uri>
            <fr:display-uri>focs-wheels</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-wheels/</fr:route>
            <fr:title text="A Finer Wheel Computation">A Finer Wheel Computation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>We now define a <html:code>wheels</html:code> function to calculate the number of wheels
in any <html:code>vehicle</html:code>. This requires <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matching</fr:link> to retrieve the
constructors and their associated arguments, around which we build the
logic:</html:p>
            <html:pre><![CDATA[# let wheels = function
  | Bike -> 2
  | Motorbike _ -> 2
  | Car robin -> if robin then 3 else 4
  | Lorry w -> w
val wheels : vehicle -> int = <fun>]]></html:pre>
            <html:p>This function consists of four clauses:</html:p>
            <html:ul><html:li>A Bike has two wheels.  This is a constant result.</html:li>
  <html:li>A Motorbike has two wheels. The <html:code>_</html:code> signifies a "wildcard" pattern match that we discard, since the engine size of the bike is not relevant to the number of wheels.</html:li>
  <html:li>A Reliant Robin has three wheels; all other cars have four. We bind <html:code>robin</html:code> to the <html:code>bool</html:code> argument and then use it in the right hand side of the pattern match, much like a <html:code>let</html:code> binding in normal code.</html:li>
  <html:li>A Lorry has the number of wheels stored with its constructor, and we simply return that.</html:li></html:ul>
            <html:p>There is no overlap between the <html:code>Motorbike</html:code> and <html:code>Lorry</html:code> cases.  Although
<html:code>Motorbike</html:code> and <html:code>Lorry</html:code> both hold an integer, OCaml takes the
constructor into account and keeps any <html:code>Motorbike</html:code> distinct from any <html:code>Lorry</html:code>.</html:p>
            <html:p>Vehicles are one example of a concept consisting of several varieties with
distinct features.  Most programming languages can represent such concepts
using something analogous to <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatypes</fr:link>.  (They are sometimes called
<html:em>union types</html:em> or <html:em>variant records</html:em> whose <html:em>tag fields</html:em> play the
role of the constructors.)</html:p>
            <html:p>A pattern may be built from the constructors of several datatypes, including
lists. A pattern may also contain integer and string constants. There is no
limit to the size of patterns or the number of clauses in a function
declaration. OCaml performs pattern-matching <fr:link href="https://dl.acm.org/citation.cfm?id=507641" type="external">efficiently</fr:link>
(you do not need to understand the details of how it optimises pattern-matching at this stage).</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/</fr:uri>
            <fr:display-uri>focs-exceptions</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-exceptions/</fr:route>
            <fr:title text="Error Handling: Exceptions">Error Handling: Exceptions</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>During a computation, what happens if something goes <html:em>wrong?</html:em></html:p>
            <html:ul><html:li>Division by zero</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">Pattern matching</fr:link> failure</html:li></html:ul>
            <html:p><html:em>Exception-handling</html:em> lets us recover gracefully.</html:p>
            <html:ul><html:li>Raising an exception abandons the current computation.</html:li>
  <html:li>Handling the exception attempts an alternative computation.</html:li>
  <html:li>The raising and handling can be far apart in the code.</html:li>
  <html:li>Errors of <html:em>different sorts</html:em> can be handled separately.</html:li></html:ul>
            <html:p>Exceptions are necessary because it is not always possible to tell in advance
whether or not a search will lead to a dead end or whether a numerical
calculation will encounter errors such as overflow or divide by zero. Rather
than just crashing, programs should check whether things have gone wrong, and
perhaps attempt an alternative computation (perhaps using a different algorithm
or higher precision). A number of modern languages provide exception handling.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/</fr:uri>
            <fr:display-uri>focs-ocaml-exceptions</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ocaml-exceptions/</fr:route>
            <fr:title text="Exceptions in OCaml">Exceptions in OCaml</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# exception Failure
exception Failure
# exception NoChange of int
exception NoChange of int
# raise Failure
Exception: Failure.]]></html:pre>
            <html:p>Each <html:code>exception</html:code> declaration introduces a distinct sort of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link>, which can
be handled separately from others. If <fr:tex display="inline"><![CDATA[E]]></fr:tex> raises an exception, then its
evaluation has failed; <html:em>handling</html:em> an exception means evaluating another
expression and returning its value instead. One exception handler can specify
separate expressions for different sorts of exceptions.</html:p>
            <html:p>Exception names are <html:em>constructors</html:em> of the special <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> <html:code>exn</html:code>.  This is a
peculiarity of OCaml that lets exception-handlers use <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>. Note that
exception <html:code>Failure</html:code> is just an error indication, while <html:code>NoChange n</html:code> carries
further information: the integer <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
            <html:pre><![CDATA[# try
    print_endline "pre exception";
    raise (NoChange 1);
    print_endline "post exception";
  with
    | NoChange _ ->
        print_endline "handled a NoChange exception"
Line 3, characters 5-23:
Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.)
pre exception
handled a NoChange exception
- : unit = ()]]></html:pre>
            <html:p>The effect of <html:code>raise &lt;expr&gt;</html:code> is to jump to the most recently-encountered
handler that matches <html:code>&lt;expr&gt;</html:code>.  The matching handler can only be found
<html:em>dynamically</html:em> (during execution); contrast with how OCaml associates occurrences
of identifiers with their matching declarations, which does not require running
the program.  A handler is introduced via the <html:code>try</html:code> keyword, which executes
the subexpression and dispatches any exceptions encountered to the corresponding
pattern match for exceptions defined in the <html:code>with</html:code> block.</html:p>
            <html:p>This is also the first time that we have encountered the <html:code>unit</html:code> type. This
represents a type that has no values, and is used to indicate that a block
has no meaningful return value.  We will come back to this when learning more
about <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local"><html:em>imperative</html:em> programming</fr:link> later on.  For now, it is sufficient to understand
that <html:code>print_endline</html:code> will print out the argument to the console output, and return
a <html:code>unit</html:code> type.  The semicolon at the end of the expression is a convenient way to
execute sequential statements that return the <html:code>unit</html:code> type.</html:p>
            <html:p>One criticism of OCaml’s exceptions is that—unlike the Java language—nothing
in a function declaration indicates which exceptions it might raise. One
alternative to exceptions is to instead return a value of datatype <html:code>option</html:code>.</html:p>
            <html:pre><![CDATA[# let x = Some 1
val x : int option = Some 1
# let y = None
val y : 'a option = None
# type 'a option = None | Some of 'a
type 'a option = None | Some of 'a]]></html:pre>
            <html:p><html:code>None</html:code> signifies an error, while <html:code>Some x</html:code> returns the solution <fr:tex display="inline"><![CDATA[x]]></fr:tex>.  This
approach looks clean, but the drawback is that many places in the code would
have to check for <html:code>None</html:code>.  Despite this, there is a builtin <html:code>option</html:code> type
in OCaml as it is so useful. We will see in later lectures how to define our
own version of <html:code>option</html:code> using polymorphic datatype definitions.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/</fr:uri>
            <fr:display-uri>focs-change-exceptions</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-change-exceptions/</fr:route>
            <fr:title text="Making Change with Exceptions">Making Change with Exceptions</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# exception Change
  let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise Change
    | c::till, amt -> if amt < 0 then raise Change
                      else try c :: change (c::till) (amt - c)
                           with Change -> change till amt
exception Change
val change : int list -> int -> int list = <fun>]]></html:pre>
            <html:p>In the <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">Lists lectures</fr:link>, we considered the problem of <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.  The greedy
algorithm presented there could not express “6 using 5 and 2” because it always
took the largest coin.  Returning <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">the list of all possible solutions</fr:link> avoids
that problem rather expensively: we only need one solution.</html:p>
            <html:p>Using <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>, we can code a <html:em>backtracking</html:em> algorithm: one that can undo
past decisions if it comes to a dead end.  The exception <html:code>Change</html:code> is raised if
we run out of coins (with a non-zero amount) or if the amount goes negative.
We always try the largest coin, but enclose the recursive call in an exception
handler, which undoes the choice if it goes wrong.</html:p>
            <html:p>Carefully observe how exceptions interact with <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  The exception
handler always undoes the <html:em>most recent</html:em> choice, leaving others possibly to
be undone later.  If making change really is impossible, then eventually
<html:code>exception Change</html:code> will be raised with no handler to catch it, and it
will be reported at top level.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-trace/</fr:uri>
            <fr:display-uri>focs-change-trace</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-change-trace/</fr:route>
            <fr:title text="Making Change: A Trace">Making Change: A Trace</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Here is the full execution. Observe how the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception handlers</fr:link> nest and how
they drop away once the given expression has returned a value.</html:p>
            <fr:tex display="block"><![CDATA[\begin{aligned}
\text{change [5; 2] 6}
  \Rightarrow &\; \text{try 5::change [5; 2] 1}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 5::change [5; 2] (-4)}\\
              &\; \text{with Change -> change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{5::(change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 2::change [2] (-1)}\\
              &\; \text{with Change -> change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{try 5::(change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{change [2] 6} \\
  \Rightarrow &\; \text{try 2::change [2] 4}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::change [2] 2}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::(try 2::change [2] 0 }\\
              &\; \text{with Change -> change [] 2)}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::[2]}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::[2; 2]}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{[2; 2; 2]}
\end{aligned}]]></fr:tex>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/</fr:uri>
            <fr:display-uri>focs-binary-trees</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-binary-trees/</fr:route>
            <fr:title text="Binary Trees, a Recursive Datatype">Binary Trees, a Recursive Datatype</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# type 'a tree =
    Lf
  | Br of 'a * 'a tree * 'a tree
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
            <html:figure>
              <html:img src="/~avsm2/fcs/bafkrmihauytafmmc5evdkkihzsaxper2thnogxohktuubaoxtrpw24qazu.svg" />
            </html:figure>
            <html:pre><![CDATA[# Br(1, Br(2, Br(4, Lf, Lf),
              Br(5, Lf, Lf)),
        Br(3, Lf, Lf))
- : int tree = Br (1, Br (2, Br (4, Lf, Lf), Br (5, Lf, Lf)), Br (3, Lf, Lf))]]></html:pre>
            <html:p>A data structure with multiple branching is called a “tree”.  Trees can
represent mathematical expressions, logical formulae, computer programs, the
phrase structure of English sentences, etc.</html:p>
            <html:p><html:em>Binary trees</html:em> are nearly as fundamental as lists.  They can provide
efficient storage and retrieval of information.  In a binary tree, each node
is empty (<fr:tex display="inline"><![CDATA[Lf]]></fr:tex>), or is a branch (<fr:tex display="inline"><![CDATA[Br]]></fr:tex>) with a label and two subtrees.</html:p>
            <html:p><fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">OCaml lists</fr:link> are a <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> and could be declared as follows:</html:p>
            <html:pre><![CDATA[# type 'a mylist =
  | Nil
  | Cons of 'a * 'a mylist
type 'a mylist = Nil | Cons of 'a * 'a mylist]]></html:pre>
            <html:p>We could even declare <html:code>::</html:code> as an infix constructor.  The only
thing we could not define is the <html:code>[...]</html:code> notation, which is
part of the OCaml grammar (although there does exist a mechanism
to use a <html:em>similar</html:em> syntax for custom indexed datatypes).</html:p>
            <html:p>A <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> type does not have to be <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.
For example, here is a simple datatype of tree shapes with no attached data
that is recursive but not polymorphic.</html:p>
            <html:pre><![CDATA[# type shape =
  | Null
  | Join of shape * shape
type shape = Null | Join of shape * shape]]></html:pre>
            <html:p>The datatype <html:code>'a option</html:code> (<fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">mentioned above</fr:link>) is the opposite – it is
polymorphic, but not recursive.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-properties/</fr:uri>
            <fr:display-uri>focs-tree-properties</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-tree-properties/</fr:route>
            <fr:title text="Basic Properties of Binary Trees">Basic Properties of Binary Trees</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec count = function
  | Lf -> 0  (* number of branch nodes *)
  | Br (v, t1, t2) -> 1 + count t1 + count t2
val count : 'a tree -> int = <fun>
# let rec depth = function
  | Lf -> 0  (* length of longest path *)
  | Br (v, t1, t2) -> 1 + max (depth t1) (depth t2)
val depth : 'a tree -> int = <fun>]]></html:pre>
            <html:p>The invariant <fr:tex display="inline"><![CDATA[\texttt {count}(t)\le  2^{\texttt {depth}(t)} - 1]]></fr:tex> holds in the functions above.</html:p>
            <html:p>Functions on trees are expressed recursively using <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.  Both
functions above are analogous to <fr:link href="/~avsm2/fcs/focs-length/" title="Efficiently Computing the Length of a List" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/" display-uri="focs-length" type="local"><fr:tex display="inline"><![CDATA[\texttt {length}]]></fr:tex> on lists</fr:link>.  Here is a third
measure of a tree’s size:</html:p>
            <html:pre><![CDATA[# let rec leaves = function
  | Lf -> 1
  | Br (v, t1, t2) -> leaves t1 + leaves t2
val leaves : 'a tree -> int = <fun>]]></html:pre>
            <html:p>This function is redundant because of a basic fact about trees, which can be
proved by induction: for every tree <fr:tex display="inline"><![CDATA[t]]></fr:tex>, we have <fr:tex display="inline"><![CDATA[\texttt {leaves}(t) =
\texttt {count}(t)+1]]></fr:tex>.  The inequality shown on the slide also has an elementary
proof by induction.</html:p>
            <html:p>A tree of depth 20 can store <fr:tex display="inline"><![CDATA[2^{20}-1]]></fr:tex> or approximately one million elements.
The access paths to these elements are short, particularly when compared with
a million-element list!</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/</fr:uri>
            <fr:display-uri>focs-ex-6</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-6/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-1/</fr:uri>
                <fr:display-uri>focs-ex-6-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-1/</fr:route>
                <fr:title text="Days of the week type">Days of the week type</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Give the declaration of an OCaml type for the days of the week. Comment on the practicality of such
a type in a calendar application.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-2/</fr:uri>
                <fr:display-uri>focs-ex-6-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-2/</fr:route>
                <fr:title text="Summing tree labels">Summing tree labels</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write an OCaml function taking a binary tree labelled with integers and returning their sum.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-3/</fr:uri>
                <fr:display-uri>focs-ex-6-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-3/</fr:route>
                <fr:title text="What ftree builds">What ftree builds</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Using the <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">definition of <html:code>'a tree</html:code></fr:link> from before:</html:p>
                <html:pre><![CDATA[type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                <html:p>Examine the following function declaration. What does <html:code>ftree (1, n)</html:code> accomplish?</html:p>
                <html:pre><![CDATA[let rec ftree k n =
  if n = 0 then Lf
  else Br (k, ftree (2 * k) (n - 1), ftree (2 * k + 1) (n - 1))]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-4/</fr:uri>
                <fr:display-uri>focs-ex-6-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-4/</fr:route>
                <fr:title text="A type for arithmetic expressions">A type for arithmetic expressions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Give the declaration of an OCaml type for arithmetic expressions that have the following
possibilities: floating-point numbers, variables (represented by strings), or expressions of the form <fr:tex display="inline"><![CDATA[-E]]></fr:tex>,
<fr:tex display="inline"><![CDATA[E+E]]></fr:tex>, <fr:tex display="inline"><![CDATA[E\times  E]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-5/</fr:uri>
                <fr:display-uri>focs-ex-6-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-5/</fr:route>
                <fr:title text="Evaluating expressions with exceptions">Evaluating expressions with exceptions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Continuing the previous exercise, write a function that evaluates an expression. If the expression
contains any variables, your function should raise an <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> indicating the variable name.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionaries/</fr:uri>
        <fr:display-uri>focs-dictionaries</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-dictionaries/</fr:route>
        <fr:title text="Dictionaries and Functional Arrays">Dictionaries and Functional Arrays</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/</fr:uri>
            <fr:display-uri>focs-dictionary-adt</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-dictionary-adt/</fr:route>
            <fr:title text="Dictionaries">Dictionaries</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>lookup: find an item in the dictionary</html:li>
<html:li>update (insert): replace (store) an item in the dictionary</html:li>
<html:li>delete: remove an item from the dictionary</html:li>
<html:li>empty: the null dictionary</html:li>
<html:li>Missing: <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> for errors in <html:code>lookup</html:code> and <html:code>delete</html:code></html:li></html:ul>
            <html:p>Ideally, an <html:em>abstract type</html:em> should provide these operations and hide the internal data structures.</html:p>
            <html:p>A dictionary attaches values to identifiers, called “keys”.  Before choosing
the internal representation for a data structure, you need to specify the full
set of operations. In fact, here we only consider <html:code>update</html:code> (associating a
value with an identifier) and <html:code>lookup</html:code> (retrieving such a value). Deletion
is more difficult and would limit our choices. Some applications may need
additional operations, such as <html:code>merge</html:code> (combining two dictionaries). We
shall see that update can be done efficiently in a functional style, without
excessive copying.</html:p>
            <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent dictionaries. Abstract
types can be declared in any modern programming language. Java’s <html:em>objects</html:em>
serve this role, as do OCaml’s modules. This course does not cover modules, and we
simply declare the dictionary operations individually.</html:p>
            <html:p>An <html:em>association list</html:em> (a list of pairs) is the simplest dictionary representation.
Lookup is by <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link>, and therefore slow: <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>. Association lists are
only usable if there are few keys in use. However, they are general in that the
keys do not need a concept of ordering, only equality.</html:p>
            <html:pre><![CDATA[# exception Missing
exception Missing
# let rec lookup a = function
  | [] -> raise Missing
  | (x, y) :: pairs ->
      if a = x then y
      else lookup a pairs
val lookup : 'a -> ('a * 'b) list -> 'b = <fun>
# let update (l, b, y) = (b, y) :: l
val update : ('a * 'b) list * 'a * 'b -> ('a * 'b) list = <fun>]]></html:pre>
            <html:p>To enter a new <html:code>(key, value)</html:code> pair, simply “cons” it to the list with <html:code>update</html:code>.
This takes constant time, which is the best we could hope for.  But the space
requirement is huge: linear in the number of updates, not in the number of
distinct keys. Obsolete entries are never deleted: that would require first
finding them, increasing the update time from <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/</fr:uri>
            <fr:display-uri>focs-bst</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bst/</fr:route>
            <fr:title text="Binary Search Trees">Binary Search Trees</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>A <html:em>dictionary</html:em> associates <html:em>values</html:em> (here, numbers) with <html:em>keys</html:em>.</html:p>
            <html:figure>
              <html:img src="/~avsm2/fcs/bafkrmifkdrvs6ut5buyf724655gdcinx637uevqiaejsmb2jgu36gaf4wq.svg" />
            </html:figure>
            <html:p>Binary search trees are an important application of <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>.  They work
for keys that have a total ordering, such as strings.  Each branch of the tree
carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree holds smaller keys; the right
subtree holds greater keys.  If the tree remains reasonably balanced, then
update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  These times
hold in the average case; given random data, the tree is likely to remain
balanced.</html:p>
            <html:p>At a given node, all keys in the left subtree are smaller (or equal) while all
trees in the right subtree are greater.</html:p>
            <html:p>An unbalanced tree has a linear access time in the worst case.  Examples
include building a tree by repeated insertions of elements in increasing or
decreasing order; there is a close resemblance to <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>.  Building a binary
search tree, then converting it to <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">inorder</fr:link>, yields a sorting algorithm called
<html:em>treesort</html:em>.</html:p>
            <html:p>Self-balancing trees, such as Red-Black trees, attain <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> in the worst
case.  They are complicated to implement.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/</fr:uri>
            <fr:display-uri>focs-bst-lookup</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bst-lookup/</fr:route>
            <fr:title text="Lookup: Seeks Left or Right">Lookup: Seeks Left or Right</fr:title>
            <fr:meta name="ocaml-deps">focs-binary-trees</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# exception Missing of string
exception Missing of string
# let rec lookup b = function
  | Br ((a, x), t1, t2) ->
      if b < a then
        lookup b t1
      else if a < b then
        lookup b t2
      else
        x
  | Lf -> raise (Missing b)
val lookup : string -> (string * 'a) tree -> 'a = <fun>]]></html:pre>
            <html:p>This has guaranteed <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> access time <html:em>if</html:em> the tree is balanced!</html:p>
            <html:p>Lookup in the <fr:link href="/~avsm2/fcs/focs-def-binary-search-tree/" title="Binary search tree" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/" display-uri="focs-def-binary-search-tree" type="local">binary search tree</fr:link> goes to the left subtree if the desired
key is smaller than the current one and to the right if it is greater.
It raises <html:code>Missing</html:code> if it encounters an empty tree.</html:p>
            <html:p>Since an ordering is involved, we have to declare the functions for a specific
type, here <html:code>string</html:code>.  Now <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Missing</html:code> mentions that type: if lookup
fails, the exception returns the missing key.  The exception could be
eliminated using type <html:code>option</html:code> of our earlier <fr:link href="/~avsm2/fcs/focs-datatypes/" title="Datatypes and Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-datatypes/" display-uri="focs-datatypes" type="local">Datatypes lecture</fr:link>, using the
constructor <html:code>None</html:code> for failure.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/</fr:uri>
            <fr:display-uri>focs-bst-update</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bst-update/</fr:route>
            <fr:title text="Update">Update</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec update k v = function
  | Lf -> Br ((k, v), Lf, Lf)
  | Br ((a, x), t1, t2) ->
      if k < a then
        Br ((a, x), update k v t1, t2)
      else if a < k then
        Br ((a, x), t1, update k v t2)
      else (* a = k *)
        Br ((a, v), t1, t2)
val update : 'a -> 'b -> ('a * 'b) tree -> ('a * 'b) tree = <fun>]]></html:pre>
            <html:p>This is also <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> as it copies the path only, and <html:em>not whole subtrees!</html:em></html:p>
            <html:p>If you are familiar with the usual update operation for this sort of tree, you
may wonder whether it can be implemented in OCaml, where there is no direct way to
replace part of a data structure by something else.</html:p>
            <html:p>The update operation is a nice piece of functional programming.  It searches
in the same manner as <fr:link href="/~avsm2/fcs/focs-bst-lookup/" title="Lookup: Seeks Left or Right" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/" display-uri="focs-bst-lookup" type="local"><html:code>lookup</html:code></fr:link>, but the recursive calls reconstruct a
new tree around the result of the update.  One subtree is updated and the
other left unchanged.  The internal representation of trees ensures that
unchanged parts of the tree are not copied, but <html:em>shared</html:em>.
Therefore, update copies only the path from the root to the new
node.  Its time and space requirements, for a reasonably balanced tree, are
both <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.</html:p>
            <html:p>The comparison between <fr:tex display="inline"><![CDATA[b]]></fr:tex> and <fr:tex display="inline"><![CDATA[a]]></fr:tex> allows three cases:</html:p>
            <html:ul><html:li>smaller: update the left subtree; share the right</html:li>
<html:li>greater: update the right subtree; share the left</html:li>
<html:li>equal: update the label and share both subtrees</html:li></html:ul>
            <html:p>Note: in the function definition, <html:code>(* a = b*)</html:code> is a comment.  Comments
in OCaml are enclosed in the brackets <html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/</fr:uri>
            <fr:display-uri>focs-tree-traversal</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-tree-traversal/</fr:route>
            <fr:title text="Aside: Traversing Trees (3 Methods)">Aside: Traversing Trees (3 Methods)</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec preorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      [v] @ preorder t1 @ preorder t2
val preorder : 'a tree -> 'a list = <fun>
# let rec inorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      inorder t1 @ [v] @ inorder t2
val inorder : 'a tree -> 'a list = <fun>
# let rec postorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      postorder t1 @ postorder t2 @ [v]
val postorder : 'a tree -> 'a list = <fun>]]></html:pre>
            <html:p><html:em>Tree traversal</html:em> means examining each node of a tree in some order.  <fr:link href="https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming" type="external">D. E.
Knuth</fr:link> has
identified three forms of tree traversal: preorder, inorder and
postorder.  We can code these “visiting orders” as functions
that convert trees into lists of labels.  Algorithms based on these notions
typically perform some action at each node; the functions above simply copy
the nodes into lists.  Consider the tree:</html:p>
            <html:figure>
              <html:img src="/~avsm2/fcs/bafkrmic3wbal56lpqlso6xcqsl6jfrutwygavrn3xds7c6ieywfjr7qdhm.svg" />
            </html:figure>
            <html:ul><html:li><html:code>preorder</html:code> visits the label first (“Polish notation”), yielding <html:code>ABDECFG</html:code></html:li>
<html:li><html:code>inorder</html:code> visits the label midway, yielding <html:code>DBEAFCG</html:code></html:li>
<html:li><html:code>postorder</html:code> visits the label last (“Reverse Polish”), yielding <html:code>DEBFGCA</html:code>. You might be familiar with this concept if you own an ancient RPN calculator!</html:li></html:ul>
            <html:p>What is the use of <html:code>inorder</html:code>? Consider applying it to a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>: the
result is a sorted list of pairs. We could use this, for example, to merge two
binary search trees. It is not difficult to transform a sorted list of pairs
into a binary search tree.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/</fr:uri>
            <fr:display-uri>focs-tree-traversal-efficient</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-tree-traversal-efficient/</fr:route>
            <fr:title text="Efficiently Traversing Trees">Efficiently Traversing Trees</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Unfortunately, the functions shown on the previous slide are quadratic in the
worst case: the appends in the recursive calls are inefficient.  To correct
that problem, we (as usual) add an accumulating argument.  Observe how
each function constructs its result list and compare with how appends were
eliminated from <html:code>quicksort</html:code> in the <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">Sorting lecture</fr:link>.</html:p>
            <html:pre><![CDATA[# let rec preord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      v :: preord (t1, preord (t2, vs))
val preord : 'a tree * 'a list -> 'a list = <fun>
# let rec inord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      inord (t1, v::inord (t2, vs))
val inord : 'a tree * 'a list -> 'a list = <fun>
# let rec postord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      postord (t1, postord (t2, v::vs))
val postord : 'a tree * 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>One can prove equations relating each of these functions to its counterpart on
the previous section.  For example:</html:p>
            <fr:tex display="block"><![CDATA[\texttt {inord}(t, vs) = \texttt {inorder}(t) @ vs]]></fr:tex>
            <html:p>These three types of tree traversal are related in that all are depth-first.
They each traverse the left subtree in full before traversing the right
subtree.  Breadth-first search (from the <fr:link href="/~avsm2/fcs/focs-queues/" title="Queues and Search Strategies" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queues/" display-uri="focs-queues" type="local">Queues lecture</fr:link>) is another
possibility.  That involves going through the levels of a tree one at a time.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-arrays/</fr:uri>
            <fr:display-uri>focs-arrays</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-arrays/</fr:route>
            <fr:title text="Arrays">Arrays</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>A conventional array is an indexed storage area.
  <html:ul><html:li>It is updated <html:em>in place</html:em> by the command <html:code>a.(k) &lt;- x</html:code></html:li>
  <html:li>The concept is inherently <html:em>imperative</html:em>.</html:li></html:ul></html:li>
<html:li>A <html:em>functional array</html:em> is a finite map from integers to data.
  <html:ul><html:li>Updating implies <html:em>copying</html:em> to return <html:code>update(A, k, x)</html:code></html:li>
  <html:li>The new array equals <html:code>A</html:code> except that <html:code>A.(k) = x</html:code>.</html:li></html:ul></html:li>
<html:li>Can we do updates efficiently?</html:li></html:ul>
            <html:p>The elements of a list can only be reached by counting from the front.
Elements of a tree are reached by following a path from the root.  An
<html:em>array</html:em> hides such structural matters; its elements are uniformly
designated by number.  Immediate access to arbitrary parts of a data structure
is called <html:em>random access</html:em>.</html:p>
            <html:p>Arrays are the dominant data structure in conventional programming languages.
The ingenious use of arrays is the key to many of the great classical
algorithms, such as Hoare’s original <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link> (the partition step) and
Warshall’s transitive-closure algorithm.</html:p>
            <html:p>The drawback is that subscripting is a chief cause of programmer error.  That
is why arrays play little role in this introductory course.</html:p>
            <html:p>Functional arrays are described below in order to illustrate another way of
using trees to organise data.  Here is a summary of basic dictionary data
structures in order of decreasing generality and increasing efficiency:</html:p>
            <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link>: Most general, needing only equality on keys, but inefficient: linear time.</html:li>
<html:li>Binary search: Needs an ordering on keys.  Logarithmic access time in the average case, but our <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link> are linear in the worst case.</html:li>
<html:li>Array subscripting: Least general, requiring keys to be integers, but even worst-case time is logarithmic.</html:li></html:ul>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/</fr:uri>
            <fr:display-uri>focs-functional-arrays</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-functional-arrays/</fr:route>
            <fr:title text="Functional Arrays as Binary Trees">Functional Arrays as Binary Trees</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>The path to element <fr:tex display="inline"><![CDATA[i]]></fr:tex> follows the <html:em>binary code</html:em> for <fr:tex display="inline"><![CDATA[i]]></fr:tex> (its “subscript”).</html:p>
            <html:figure>
              <html:img src="/~avsm2/fcs/bafkrmifetc2v73r7qxnzo6bthiblab2tezbaqvmovq7e4q6vgdl5ewr3wi.svg" />
            </html:figure>
            <html:p>This simple representation (credited to W. Braun) ensures that the tree is
balanced.  Complexity of access is always <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>, which is optimal.  For
actual running time, access to conventional arrays is much faster: it requires
only a few hardware instructions.  Array access is often taken to be <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>,
which (as always) presumes that hardware limits are never exceeded.</html:p>
            <html:p>The lower bound for array subscripts (or “indices”) is one.  The upper bound starts at zero
(which signifies the empty array) and can grow without limit.  Inspection of
the diagram above should make it clear that these trees are always balanced:
the left subtree can have at most one node more than the right subtree,
recursively all the way down.  (This assumes that the array is defined for
subscripts <fr:tex display="inline"><![CDATA[1\ldots  n]]></fr:tex> with no gaps; an array defined only for odd numbers, for
example, would obviously be unbalanced.)</html:p>
            <html:p>The numbers in the diagram above are not the labels of branch nodes, but
indicate the positions of array elements. For example, the label corresponding
to <fr:tex display="inline"><![CDATA[A[2]]]></fr:tex> is at the position shown. The nodes of a functional array are
labelled with the data we want to store, not with these integers.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/</fr:uri>
            <fr:display-uri>focs-funarray-lookup</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-funarray-lookup/</fr:route>
            <fr:title text="The Lookup Function">The Lookup Function</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# exception Subscript
  let rec sub = function
  | Lf, _ -> raise Subscript  (* Not found *)
  | Br (v, t1, t2), k ->
      if k = 1 then v
      else if k mod 2 = 0 then
        sub (t1, k / 2)
      else
        sub (t2, k / 2)
exception Subscript
val sub : 'a tree * int -> 'a = <fun>
# let rec sub = function (* Alternative implementation *)
  | Lf, _ -> raise Subscript
  | Br (v, t1, t2), 1 -> v
  | Br (v, t1, t2), k when k mod 2 = 0 -> sub (t1, k / 2)
  | Br (v, t1, t2), k -> sub (t2, k / 2)
val sub : 'a tree * int -> 'a = <fun>]]></html:pre>
            <html:p>Notice that we have used a new keyword <html:code>when</html:code> above, which changes
pattern clauses to be only matched if the expression evalutes to true.
This can be equivalently expressed by moving the corresponding
checks into an <html:code>if</html:code> clause on the right hand side of the <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern match</fr:link>,
but is often more readable using <html:code>when</html:code> (as above).</html:p>
            <html:p>The lookup function <html:code>sub</html:code>, divides the subscript by 2 until 1 is
reached.  If the remainder is 0 then the function follows the left subtree,
otherwise the right.  If it reaches a leaf, it signals error by raising
<fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Subscript</html:code>.</html:p>
            <html:p>Array access can also be understood in terms of the subscript’s binary code.
Because the subscript must be a positive integer, in binary it has a leading
one.  Discard this one and reverse the remaining bits.  Interpreting zero
as <html:em>left</html:em> and one as <html:em>right</html:em> yields the path from the root to the
subscript.</html:p>
            <html:p>Popular literature often explains the importance of binary as being led by
hardware: because a circuit is either on or off.  The truth is almost the
opposite.  Designers of digital electronics go to a lot of trouble to suppress
the continuous behaviour that would naturally arise.  The real reason why
binary is important is its role in algorithms: an <html:code>if-then-else</html:code> decision leads
to binary branching.</html:p>
            <html:p>Data structures, such as trees, and algorithms, such as <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link>, use binary
branching in order to reduce a cost from <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  Two is the
smallest integer divisor that achieves this reduction.  (Larger divisors are
only occasionally helpful, as in the case of B-trees, where they reduce the
constant factor.)  The simplicity of binary arithmetic compared with decimal
arithmetic is just another instance of the simplicity of algorithms based on
binary choices.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-update/</fr:uri>
            <fr:display-uri>focs-funarray-update</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-funarray-update/</fr:route>
            <fr:title text="The Update Function">The Update Function</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec update = function
  | Lf, k, w ->
      if k = 1 then
        Br (w, Lf, Lf)
      else
        raise Subscript  (* Gap in tree *)
  | Br (v, t1, t2), k, w ->
      if k = 1 then
        Br (w, t1, t2)
      else if k mod 2 = 0 then
        Br (v, update (t1, k / 2, w), t2)
      else
        Br (v, t1, update (t2, k / 2, w))
val update : 'a tree * int * 'a -> 'a tree = <fun>]]></html:pre>
            <html:p>The <html:code>update</html:code> function also divides the subscript repeatedly by two.  When it
reaches a value of one, it has identified the element position.  Then it
replaces the branch node by another branch with the new label.</html:p>
            <html:p>A leaf may be replaced by a branch, extending the array, provided no
intervening nodes have to be generated.  This suffices for arrays without gaps
in their subscripting.  (The data structure can be modified to allow <html:em>sparse</html:em>
arrays, where most subscript positions are undefined.) Exception <fr:link href="/~avsm2/fcs/focs-funarray-lookup/" title="The Lookup Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/" display-uri="focs-funarray-lookup" type="local"><html:code>Subscript</html:code></fr:link>
indicates that the subscript position does not exist and cannot be created.
This use of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link> is not easily replaced by <html:code>None</html:code> and <html:code>Some</html:code>.</html:p>
            <html:p>Note that there are two tests involving <fr:tex display="inline"><![CDATA[k=1]]></fr:tex>.  If we have reached a leaf,
it returns a branch, extending the array by one.  If we are still at a branch
node, then the effect is to update an existing array element.</html:p>
            <html:p>A similar function can <html:em>shrink</html:em> an array by one.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/</fr:uri>
            <fr:display-uri>focs-ex-7</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-7/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-1/</fr:uri>
                <fr:display-uri>focs-ex-7-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-1/</fr:route>
                <fr:title text="Insertion order in search trees">Insertion order in search trees</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Draw the <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link> that arises from successively inserting the following pairs into the
empty tree: <html:code>("Alice", 6)</html:code>, <html:code>("Tobias", 2)</html:code>, <html:code>("Gerald", 8)</html:code>, <html:code>("Lucy", 9)</html:code>. Then repeat this
task using the order <html:code>("Gerald", 8)</html:code>, <html:code>("Alice", 6)</html:code>, <html:code>("Lucy", 9)</html:code>, <html:code>("Tobias", 2)</html:code>. Why are
results different?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-2/</fr:uri>
                <fr:display-uri>focs-ex-7-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-2/</fr:route>
                <fr:title text="Insertion with collision detection">Insertion with collision detection</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an insertion function for <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link>. It should resemble the existing <fr:link href="/~avsm2/fcs/focs-bst-update/" title="Update" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/" display-uri="focs-bst-update" type="local"><html:code>update</html:code></fr:link>
function except that it should raise the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Collision</html:code> if the item to be inserted is already
present.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-3/</fr:uri>
                <fr:display-uri>focs-ex-7-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-3/</fr:route>
                <fr:title text="Returning the old value on collision">Returning the old value on collision</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Continuing the previous exercise, it would be natural for exceptional <html:code>Collision</html:code> to return the
value previously stored in the dictionary. Why is that goal difficult to achieve?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-4/</fr:uri>
                <fr:display-uri>focs-ex-7-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-4/</fr:route>
                <fr:title text="Deleting from a search tree">Deleting from a search tree</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Describe an algorithm for deleting an entry from a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>. Comment on the suitability of
your approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-5/</fr:uri>
                <fr:display-uri>focs-ex-7-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-5/</fr:route>
                <fr:title text="Implementing deletion">Implementing deletion</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code the delete function outlined in the previous exercise.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-6/</fr:uri>
                <fr:display-uri>focs-ex-7-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-6/</fr:route>
                <fr:title text="Quadratic traversals">Quadratic traversals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>preorder</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>postorder</html:code></fr:link> all require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time in the worst
case, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the size of the tree.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-7/</fr:uri>
                <fr:display-uri>focs-ex-7-7</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-7/</fr:route>
                <fr:title text="Linear traversals">Linear traversals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>preord</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>inord</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>postord</html:code></fr:link> all take linear time in the size of the
tree.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-8/</fr:uri>
                <fr:display-uri>focs-ex-7-8</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-8/</fr:route>
                <fr:title text="Shifting a functional array">Shifting a functional array</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a function to remove the first element from a <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional array</fr:link>. All the other elements are to
have their subscripts reduced by one. The cost of this operation should be linear in the size of the
array.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/</fr:uri>
        <fr:display-uri>focs-functions</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-functions/</fr:route>
        <fr:title text="Functions as Values">Functions as Values</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <html:p>In OCaml, functions can be</html:p>
        <html:ul><html:li>passed as arguments to other functions,</html:li>
  <html:li>returned as results,</html:li>
  <html:li>put into lists, trees, etc.,</html:li>
  <html:li>but <html:em>not</html:em> tested for equality.</html:li></html:ul>
        <html:pre><![CDATA[# [(fun n -> n * 2);
   (fun n -> n * 3);
   (fun n -> n + 1)]
- : (int -> int) list = [<fun>; <fun>; <fun>]]]></html:pre>
        <html:p>Progress in programming languages can be measured by what abstractions they
admit.  Conditional expressions (descended from conditional jumps based
on the sign of some numeric variable) and parametric types such as
<fr:tex display="inline"><![CDATA[\alpha \,\texttt {list}]]></fr:tex> are examples.  The idea that functions could be used
as values in a computation arose early, but it took some time before the idea
was fully realised.  Many programming languages let functions be passed as
arguments to other functions, but few take the trouble needed to allow
functions to be returned as results.</html:p>
        <html:p>In mathematics, a <html:em>functional</html:em> or <html:em>higher-order function</html:em> is a
function that operates on other functions.  Many functionals are familiar from
mathematics: for example, the differential operator maps functions to their
derivatives, which are also functions.  To a mathematician, a function is
typically an infinite, uncomputable object.  We use OCaml functions to represent
algorithms.  Sometimes they represent infinite collections of data given by
computation rules.</html:p>
        <html:p>Functions cannot be compared for equality. We could compare the machine
addresses of the compiled code, but that would merely be a test of identity: it
would regard any two separate functions as unequal even if they were compiled
from identical pieces of source code.  Such a low-level feature has no place in
a principled language.</html:p>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/</fr:uri>
            <fr:display-uri>focs-anonymous-functions</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-anonymous-functions/</fr:route>
            <fr:title text="Functions Without Names">Functions Without Names</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>If functions are to be regarded as computational values, then we need a
notation for them.  The <html:code>fun</html:code> notation expresses a non-recursive function
value without giving the function a name.</html:p>
            <html:p><fr:tex display="inline"><![CDATA[\tt  fun\;x\;\rightarrow  E]]></fr:tex> is the function <fr:tex display="inline"><![CDATA[f]]></fr:tex> such that <fr:tex display="inline"><![CDATA[f(x)=E]]></fr:tex>.
The function <html:code>fun n -&gt; n*2</html:code> is a <html:em>doubling function</html:em>.</html:p>
            <html:pre><![CDATA[# fun n -> n * 2
- : int -> int = <fun>
# (fun n -> n * 2) 17
- : int = 34]]></html:pre>
            <html:p>The main purpose of <html:code>fun</html:code>-notation is to package up small expressions that are to be
applied repeatedly using some other function.
The expression <html:code>fun n -&gt; n*2</html:code> has the same value as the identifier
<html:code>double</html:code>, declared as follows:</html:p>
            <html:pre><![CDATA[# let double n = n * 2
val double : int -> int = <fun>]]></html:pre>
            <html:p>The <html:code>fun</html:code> notation can also do <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matching</fr:link>, and the <html:code>function</html:code> keyword
adds an anonymous variable name to pattern match against.  The following functions
are all equivalent, with the latter definitions bound to the <html:code>is_zero</html:code> value and the earlier ones anonymous:</html:p>
            <html:pre><![CDATA[# fun x -> match x with 0 -> true | _ -> false
- : int -> bool = <fun>
# function 0 -> true | _ -> false
- : int -> bool = <fun>
# let is_zero = fun x -> match x with 0 -> true | _ -> false
val is_zero : int -> bool = <fun>
# let is_zero = function 0 -> true | _ -> false
val is_zero : int -> bool = <fun>]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/</fr:uri>
            <fr:display-uri>focs-currying</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-currying/</fr:route>
            <fr:title text="Curried Functions">Curried Functions</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>A <html:em>curried function</html:em> returns another function as its result. We use
the string concetenation operator <html:code>(^)</html:code> to illustrate how this works.</html:p>
            <html:pre><![CDATA[# (^)
- : string -> string -> string = <fun>
# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let promote = prefix "Senior "
val promote : string -> string = <fun>
# prefix "Junior " "Professor"
- : string = "Junior Professor"
# promote "Professor"
- : string = "Senior Professor"]]></html:pre>
            <html:p>A short form for the definition of <html:code>prefix</html:code> is simply to pass multiple
arguments to the function definition.  The following two definitions
are equivalent in OCaml:</html:p>
            <html:pre><![CDATA[# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>]]></html:pre>
            <html:p>Currying is the technique of expressing a function taking multiple arguments as nested functions, each taking a single argument.
The <html:code>fun</html:code>-notation lets us package <html:code>n*2</html:code> as the function
<html:code>fun n -&gt; n * 2</html:code>, but what if there are several variables, as in
<html:code>fun n -&gt; n * 2 + k</html:code>?  A function of two arguments could be coded using
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> on pairs, writing <html:code>fun (n, k) -&gt; n * 2 + k</html:code>.</html:p>
            <html:p>Currying is an alternative, where we <html:em>nest</html:em> the <html:code>fun</html:code>-notation:</html:p>
            <html:pre><![CDATA[# fun k -> fun n -> n * 2 + k
- : int -> int -> int = <fun>]]></html:pre>
            <html:p>Applying this curried function to the argument 1 yields another function, in which <html:code>k</html:code> has been replaced by 1:</html:p>
            <html:pre><![CDATA[# let fn = fun k -> fun n -> n * 2 + k
val fn : int -> int -> int = <fun>
# let fn' = fn 1 (* n * 2 + 1 *)
val fn' : int -> int = <fun>
# fn' 3  (* 3 * 2 + 1 *)
- : int = 7]]></html:pre>
            <html:p>And this function, when applied to 3, yields the result 7. The two arguments are supplied one after another.</html:p>
            <html:p>The example on the slide is similar but refers to the expression <html:code>a^b</html:code>,
where <html:code>^</html:code> is the infix operator for string concatenation. Function <html:code>promote</html:code> binds the first argument of <html:code>prefix</html:code> to
<html:code>"Professor"</html:code>; the resulting function prefixes that title
to any string to which it is applied.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-curry-shorthand/</fr:uri>
            <fr:display-uri>focs-curry-shorthand</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-curry-shorthand/</fr:route>
            <fr:title text="Shorthand for Curried Functions">Shorthand for Curried Functions</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>A function-returning function is just a function of two arguments.</html:p>
            <html:p>This <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link> syntax is nicer than nested <html:code>fun</html:code> binders:</html:p>
            <html:pre><![CDATA[# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>
# let dub = prefix "Sir "
val dub : string -> string = <fun>]]></html:pre>
            <html:p>Curried functions allows <html:em>partial application</html:em> (to the first argument).</html:p>
            <html:p>In OCaml, an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-argument curried function <html:code>f</html:code> can be declared using the syntax:</html:p>
            <fr:tex display="block"><![CDATA[\tt  let \; f \; x_1 \: \ldots  \: x_{n} \: = \: E]]></fr:tex>
            <html:p>and applied using the syntax:</html:p>
            <fr:tex display="block"><![CDATA[\tt  \; E_1 \; \ldots  \; E_n]]></fr:tex>
            <html:p>If <html:code>f</html:code> is not recursive, then it is equivalent to the function expressed via nesting as follows:</html:p>
            <fr:tex display="block"><![CDATA[\tt  fun \; x_1 \; \rightarrow  \cdots  \rightarrow  fun \; x_{n} \rightarrow  E ]]></fr:tex>
            <html:p>We now have two ways of expressing functions of multiple arguments: either by
passing a pair of arguments or by currying.  Currying allows <html:em>partial application</html:em>
which is useful when fixing the first argument yields a function
that is interesting in its own right.  An example from mathematics is the
function <fr:tex display="inline"><![CDATA[x^y]]></fr:tex>, where fixing <fr:tex display="inline"><![CDATA[y=2]]></fr:tex> yields a function in <fr:tex display="inline"><![CDATA[x]]></fr:tex> alone, namely
squaring. Similarly, <fr:tex display="inline"><![CDATA[y=3]]></fr:tex> yields cubing, while <fr:tex display="inline"><![CDATA[y=1]]></fr:tex> yields the identity
function.</html:p>
            <html:p>Though the function <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> (which returns the head of a list) is not
curried, it may be used with the curried application syntax in some
expressions:</html:p>
            <html:pre><![CDATA[# List.hd [dub; promote] "Hamilton"
- : string = "Sir Hamilton"]]></html:pre>
            <html:p>Here <html:code>List.hd</html:code> is applied to a list of functions, and the resulting function
<html:code>dub</html:code> is then applied to the string <html:code>"Hamilton"</html:code>.  The idea of
executing code stored in data structures reaches its full development in
<html:em>object-oriented</html:em> programming, like in Java.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/</fr:uri>
            <fr:display-uri>focs-partial-application</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-partial-application/</fr:route>
            <fr:title text="Partial Application: A Curried Insertion Sort">Partial Application: A Curried Insertion Sort</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let insort lessequal =
    let rec ins x = function
      | [] -> [x]
      | y::ys -> if lessequal x y then x :: y :: ys
                 else y :: ins x ys
    in
    let rec sort = function
      | [] -> []
      | x::xs -> ins x (sort xs)
    in
    sort
val insort : ('a -> 'a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">sorting functions</fr:link> we discussed in earlier lectures are coded to sort floating-point
numbers.  They can be generalised to an arbitrary ordered type by passing the
ordering predicate <html:code>lessequal</html:code> as an argument.</html:p>
            <html:p>Functions <html:code>ins</html:code> and <html:code>sort</html:code> are declared locally, referring to <html:code>lessequal</html:code>.
Though it may not be obvious, <html:code>insort</html:code> is a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link>.  Given its first
argument, a predicate for comparing some particular type of items, it returns
the function <html:code>sort</html:code> for sorting lists of that type of items.</html:p>
            <html:p>Some examples of its use:</html:p>
            <html:pre><![CDATA[# insort (<=) [5; 3; 9; 8]
- : int list = [3; 5; 8; 9]
# insort (<=) ["bitten"; "on"; "a"; "bee"]
- : string list = ["a"; "bee"; "bitten"; "on"]
# insort (>=) [5; 3; 9; 8]
- : int list = [9; 8; 5; 3]]]></html:pre>
            <html:p>An obscure point: the syntax <html:code>(&lt;=)</html:code> denotes the comparison operator as a
function, which is then given to <html:code>insort</html:code>.  Passing the relation <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex> for
<html:code>lessequal</html:code> gives a decreasing sort.  This is no coding trick; it is justified
in mathematics, since if <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> is a partial ordering then so is <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/</fr:uri>
            <fr:display-uri>focs-map</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-map/</fr:route>
            <fr:title text="map: the “Apply to All” Function">map: the “Apply to All” Function</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec map f = function
    | [] -> []
    | x::xs -> (f x) :: map f xs
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
# map (fun s -> s ^ "ppy") ["Hi"; "Ho"]
- : string list = ["Hippy"; "Hoppy"]
# map (map double) [[1]; [2; 3]]
- : int list list = [[2]; [4; 6]]]]></html:pre>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>map</html:code> applies a function to every element of a list,
returning a list of the function’s results.  “Apply to all” is a fundamental
operation and we shall see several applications of it below.  We
again see the advantages of <html:code>fun</html:code>-notation, <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">currying</fr:link> and
<html:code>map</html:code>.  If we did not have them, the first use of <html:code>map</html:code> in the above code block
would require a preliminary function declaration:</html:p>
            <html:pre><![CDATA[# let rec sillylist = function
    | [] -> []
    | s::ss -> (s ^ "ppy") :: sillylist ss
val sillylist : string list -> string list = <fun>]]></html:pre>
            <html:p>An expression containing several applications of functionals—such as our
second example—can abbreviate a long series of declarations.  Sometimes this
coding style is cryptic, but it can be clear as crystal.  Treating functions
as values lets us capture common program structures once and for all.</html:p>
            <html:p>In the second example, <fr:link href="/~avsm2/fcs/focs-anonymous-functions/" title="Functions Without Names" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/" display-uri="focs-anonymous-functions" type="local"><html:code>double</html:code></fr:link> is the obvious integer doubling function we
defined earlier.  Note that <html:code>map</html:code> is a built-in OCaml function in the
form of <html:code>List.map</html:code>.  OCaml’s standard library includes, among much else, many
list functions.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/</fr:uri>
            <fr:display-uri>focs-transpose</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-transpose/</fr:route>
            <fr:title text="Example: Matrix Transpose">Example: Matrix Transpose</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tex display="block"><![CDATA[
\begin {pmatrix}
           a   & b & c \\
           d   & e & f
   \end {pmatrix}^T =
   \begin {pmatrix}
        a & d     \\
        b & e     \\
        c & f
\end {pmatrix}
]]></fr:tex>
            <html:pre><![CDATA[# let rec transp = function
    | []::_ -> []
    | rows -> (map List.hd rows) ::
              (transp (map List.tl rows))
val transp : 'a list list -> 'a list list = <fun>]]></html:pre>
            <html:p>A matrix can be viewed as a list of rows, each row a list of matrix elements.
This representation is not especially efficient compared with the conventional
one (using arrays).  Lists of lists turn up often, though, and we can see how
to deal with them by taking familiar matrix operations as examples.
<html:em>ML for the Working Programmer</html:em> goes as far as Gaussian elimination,
which presents surprisingly few difficulties.</html:p>
            <html:p>The transpose of the matrix
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix} a & b & c \\
                           d & e & f\end {smallmatrix}\right )]]></fr:tex>
is
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix}
        a & d     \\
        b & e     \\
        c & f
   \end {smallmatrix}\right )]]></fr:tex>,
which in OCaml corresponds to the following transformation on lists of lists:</html:p>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {[[a; b; c]; [d; e; f]]} \Rightarrow & \text { [[a; d]; [b; e]; [c; f]]}
\end {aligned}
]]></fr:tex>
            <html:p>The workings of function <html:code>transp</html:code> are simple.  If <html:code>rows</html:code> is the
matrix to be transposed, then <html:code>map hd</html:code> extracts its first column and
<html:code>map tl</html:code> extracts its second column:</html:p>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {map hd rows} \Rightarrow  & \text { [a; d]}\\
\text {map tl rows} \Rightarrow  & \text { [[b; c]; [e; f]]}
\end {aligned}
]]></fr:tex>
            <html:p>A recursive call transposes the latter matrix, which is then given the column
<html:code>[a; d]</html:code> as its first row.
The two functions expressed using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> would otherwise have to be declared
separately.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matrix-multiplication/</fr:uri>
            <fr:display-uri>focs-matrix-multiplication</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-matrix-multiplication/</fr:route>
            <fr:title text="Review of Matrix Multiplication">Review of Matrix Multiplication</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tex display="block"><![CDATA[
\begin {pmatrix} A_1 & \cdots  & A_k \end {pmatrix}  \cdot 
   \begin {pmatrix}
        B_1 \\ \vdots  \\ B_k
   \end {pmatrix}   =
   \begin {pmatrix}
        A_1 B_1 + \cdots  + A_k B_k
   \end {pmatrix}
]]></fr:tex>
            <html:p>The right side is the <html:em>vector dot product</html:em> <fr:tex display="inline"><![CDATA[\vec {A}\cdot  \vec {B}]]></fr:tex>.
Repeat for each <html:em>row</html:em> of <fr:tex display="inline"><![CDATA[A]]></fr:tex> and <html:em>column</html:em> of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
            <html:p>The <html:em>dot product</html:em> of two vectors is</html:p>
            <fr:tex display="block"><![CDATA[ (a_1,\ldots ,a_k) \cdot  (b_1,\ldots ,b_k) = a_1b_1 + \cdots  + a_kb_k ]]></fr:tex>
            <html:p>A simple case of matrix multiplication is when <fr:tex display="inline"><![CDATA[A]]></fr:tex> consists of a single row
and <fr:tex display="inline"><![CDATA[B]]></fr:tex> consists of a single column.  Provided <fr:tex display="inline"><![CDATA[A]]></fr:tex> and <fr:tex display="inline"><![CDATA[B]]></fr:tex> contain the same
number <fr:tex display="inline"><![CDATA[k]]></fr:tex> of elements, multiplying them yields a <fr:tex display="inline"><![CDATA[1\times 1]]></fr:tex> matrix whose
single element is the dot product shown above.</html:p>
            <html:p>If <fr:tex display="inline"><![CDATA[A]]></fr:tex> is an <fr:tex display="inline"><![CDATA[m\times  k]]></fr:tex> matrix and <fr:tex display="inline"><![CDATA[B]]></fr:tex> is a <fr:tex display="inline"><![CDATA[k\times  n]]></fr:tex> matrix
then <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix.
For each <fr:tex display="inline"><![CDATA[i]]></fr:tex> and <fr:tex display="inline"><![CDATA[j]]></fr:tex>, the <fr:tex display="inline"><![CDATA[(i,j)]]></fr:tex> element of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is the dot
product of row <fr:tex display="inline"><![CDATA[i]]></fr:tex> of <fr:tex display="inline"><![CDATA[A]]></fr:tex> with column <fr:tex display="inline"><![CDATA[j]]></fr:tex> of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
            <fr:tex display="block"><![CDATA[
\begin {pmatrix}
        2 & 0 \\
        3 &-1 \\
        0 & 1 \\
        1 & 1
   \end {pmatrix}
   \begin {pmatrix}
        1 & 0 & 2 \\
        4 &-1 & 0
   \end {pmatrix}   =
   \begin {pmatrix}
        2 & 0 & 4 \\
       -1 & 1 & 6 \\
        4 &-1 & 0 \\
        5 &-1 & 2
\end {pmatrix}
]]></fr:tex>
            <html:p>The (1, 1) element above is computed by</html:p>
            <fr:tex display="block"><![CDATA[ (2,0)\cdot (1,4) = 2\times 1 + 0\times 4 = 2. ]]></fr:tex>
            <html:p>Coding matrix multiplication in a conventional programming language usually
involves three nested loops.  It is hard to avoid mistakes in the subscripting,
which often runs slowly due to redundant internal calculations.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matmul-ocaml/</fr:uri>
            <fr:display-uri>focs-matmul-ocaml</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-matmul-ocaml/</fr:route>
            <fr:title text="Matrix Multiplication in OCaml">Matrix Multiplication in OCaml</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p><html:em>Dot product</html:em> of two vectors—a <html:em><fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link></html:em></html:p>
            <html:pre><![CDATA[# let rec dotprod xs ys =
    match xs, ys with
    | [], [] -> 0.0
    | x::xs, y::ys ->  (x *. y) +. (dotprod xs ys)
Lines 2-4, characters 5-51:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
([], _::_)
val dotprod : float list -> float list -> float = <fun>]]></html:pre>
            <html:p>
              <html:em>Matrix product</html:em>
            </html:p>
            <html:pre><![CDATA[# let rec matprod arows brows =
    let cols = transp brows in
    map (fun row -> map (dotprod row) cols) arows
val matprod : float list list -> float list list -> float list list = <fun>]]></html:pre>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local"><html:code>transp brows</html:code></fr:link> converts <fr:tex display="inline"><![CDATA[B]]></fr:tex> into a list of columns, yielding a
list whose elements are the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Each row of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is
obtained by multiplying a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex> by the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
            <html:p>Because <html:code>dotprod</html:code> is curried, it can be applied to a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The
resulting function is applied to all the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  We have another
example of currying and partial application.</html:p>
            <html:p>The outer <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> applies <html:code>dotprod</html:code> to each row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The inner
<html:code>map</html:code>, using <html:code>fun</html:code>-notation, applies <html:code>dotprod row</html:code> to each
column of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Compare with the version in <html:em>ML for the Working
  Programmer</html:em> (page 89) which does not use <html:code>map</html:code> and requires two
additional function declarations.</html:p>
            <html:p>In the dot product function, the two vectors must have the same length.
Otherwise, <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Match_failure</html:code> is raised.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/</fr:uri>
            <fr:display-uri>focs-predicate-functionals</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-predicate-functionals/</fr:route>
            <fr:title text="List Functionals for Predicates">List Functionals for Predicates</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec exists p = function
  | [] -> false
  | x::xs -> (p x) || (exists p xs)
val exists : ('a -> bool) -> 'a list -> bool = <fun>
# let rec filter p = function
  | [] -> []
  | x::xs ->
      if p x then
        x :: filter p xs
      else
        filter p xs
val filter : ('a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>A <html:em>predicate</html:em> is a <html:em>boolean-valued</html:em> function.</html:p>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>exists</html:code> transforms a predicate into a predicate over
lists.  Given a list, <html:code>exists p</html:code> tests whether or not some list element
satisfies <html:code>p</html:code> (making it return <html:code>true</html:code>).  If it finds one, it stops
searching immediately, thanks to the behaviour of the lazy <html:code>||</html:code> operator.</html:p>
            <html:p>Dually, we have a functional to test whether all list elements satisfy the
predicate.  If it finds a counterexample then it, too, stops searching.</html:p>
            <html:pre><![CDATA[# let rec all p = function
  | [] -> true
  | x::xs -> (p x) && all p xs
val all : ('a -> bool) -> 'a list -> bool = <fun>]]></html:pre>
            <html:p>The <html:code>filter</html:code> functional, like <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>, transforms lists.  It applies a
predicate to all the list elements, but instead of returning the
resulting values (which could only be <html:code>true</html:code> or <html:code>false</html:code>), it returns
the list of elements satisfying the predicate.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-applications/</fr:uri>
            <fr:display-uri>focs-predicate-applications</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-predicate-applications/</fr:route>
            <fr:title text="Applications of the Predicate Functionals">Applications of the Predicate Functionals</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let member y xs =
    exists (fun x -> x=y) xs
val member : 'a -> 'a list -> bool = <fun>
# let inter xs ys =
    filter (fun x -> member x ys) xs
val inter : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
            <html:p>
              <html:em>Testing whether two lists have no common elements</html:em>
            </html:p>
            <html:pre><![CDATA[# let disjoint xs ys =
    all (fun x -> all (fun y -> x<>y) ys) xs
val disjoint : 'a list -> 'a list -> bool = <fun>]]></html:pre>
            <html:p>The Lists lecture presented the function <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link>, which tests whether a
specified value can be found as a list element, and <html:code>inter</html:code>, which returns the
“intersection” of two lists: the list of elements they have in common.</html:p>
            <html:p>But remember: the purpose of list <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> is not to replace the
declarations of popular functions, which probably are available already.  It is
to eliminate the need for separate declarations of ad-hoc functions.  When they
are nested, like the calls to <html:code>all</html:code> in <html:code>disjoint</html:code> above, the
inner functions are almost certainly one-offs, not worth declaring separately.</html:p>
            <html:p>Our primitives themselves can be seen as a programming language.  Part of the
task of programming is to extend our programming language with notation for
solving the problem at hand.  The levels of notation that we define should
correspond to natural <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">levels of abstraction</fr:link> in the problem domain.</html:p>
            <html:p>Historical Note:
Alonzo Church’s <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus gave a simple syntax, <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-notation,
for expressing functions.  It is the direct precursor of OCaml’s
<html:code>fun</html:code>-notation.  It was soon shown that his system was equivalent in
computational power to Turing machines, and <html:em>Church’s thesis</html:em> states that
this defines precisely the set of functions that can be computed effectively.</html:p>
            <html:p>The <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus had a tremendous influence on the design of functional
programming languages.  McCarthy’s Lisp was something of a false start; it
interpreted variable binding incorrectly, an error that stood for some 20
years.  But in 1966, Peter Landin (of Queen Mary College, University of London)
sketched out the main features of functional languages.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/</fr:uri>
            <fr:display-uri>focs-ex-8</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-8/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-1/</fr:uri>
                <fr:display-uri>focs-ex-8-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-1/</fr:route>
                <fr:title text="The argument-swapping functional">The argument-swapping functional</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What does the following function do, and what are its uses?</html:p>
                <html:pre><![CDATA[let sw f x y = f y x]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-2/</fr:uri>
                <fr:display-uri>focs-ex-8-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-2/</fr:route>
                <fr:title text="Lexicographic orderings">Lexicographic orderings</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>There are many ways of combining orderings. The <html:code>lexicographic ordering</html:code> uses two keys for
comparisons. It is specified by</html:p>
                <fr:tex display="block"><![CDATA[(x',y')<(x,y)\iff  x'<x \vee  (x'=x \wedge  y'<y).]]></fr:tex>
                <html:p>Write an OCaml function to lexicographically combine two orderings, supplied as functions. Explain
how it allows function <fr:link href="/~avsm2/fcs/focs-partial-application/" title="Partial Application: A Curried Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/" display-uri="focs-partial-application" type="local"><html:code>insort</html:code></fr:link> to sort a list of pairs.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-3/</fr:uri>
                <fr:display-uri>focs-ex-8-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-3/</fr:route>
                <fr:title text="Mapping over lists of lists">Mapping over lists of lists</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Without using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> write a function <html:code>map2</html:code> such that <html:code>map2 f</html:code> is equivalent to <html:code>map (map f)</html:code>. The
obvious solution requires declaring two recursive functions. Try to get away with only one by
exploiting nested <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-4/</fr:uri>
                <fr:display-uri>focs-ex-8-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-4/</fr:route>
                <fr:title text="A map for options">A map for options</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>The type <html:code>'a option</html:code>, declared below, can be viewed as a type of lists having at most one element.
(It is typically used as an alternative to <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">exceptions</fr:link>.) Declare an analogue of the function <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>
for type <html:code>'a option</html:code>.</html:p>
                <html:pre><![CDATA[type 'a option = None | Some of 'a]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-5/</fr:uri>
                <fr:display-uri>focs-ex-8-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-5/</fr:route>
                <fr:title text="Making change with map">Making change with map</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Recall the making change function of <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">More on Lists</fr:link>:</html:p>
                <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                <html:p>Function <html:code>allc</html:code> applies the function ‘cons a <html:code>c</html:code>’ to every element of a list. Eliminate it by
declaring a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried</fr:link> cons function and applying <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sequences/</fr:uri>
        <fr:display-uri>focs-sequences</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-sequences/</fr:route>
        <fr:title text="Sequences, or Lazy Lists">Sequences, or Lazy Lists</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-pipeline/</fr:uri>
            <fr:display-uri>focs-pipeline</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-pipeline/</fr:route>
            <fr:title text="A Pipeline">A Pipeline</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tex display="block"><![CDATA[
\fbox {\textit {Producer}} \to  \fbox {\textit {Filter}} \to \cdots \to 
 \fbox {\textit {Filter}} \to  \fbox {\textit {Consumer}}
]]></fr:tex>
            <html:ul><html:li>Produce sequence of items</html:li>
  <html:li>Filter sequence in stages</html:li>
  <html:li>Consume results as needed</html:li>
  <html:li><html:em><fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">Lazy lists</fr:link></html:em> join the stages together</html:li></html:ul>
            <html:p>Two types of program can be distinguished.  A sequential program
accepts a problem to solve, processes for a while, and finally terminates
with its result.  A typical example is the huge numerical simulations that are
run on supercomputers.  Most of our OCaml functions also fit this model.</html:p>
            <html:p>At the other extreme are <html:em>reactive</html:em> programs, whose job is to interact
with the environment.  They communicate constantly during their operation and
run for as long as is necessary.  A typical example is the software that
controls many modern aircraft.  Reactive programs often consist of
<html:em>concurrent processes</html:em> running at the same time and communicating with
one another.</html:p>
            <html:p>Concurrency is too difficult to consider in this course, but we can model
simple pipelines such as that shown above.  The <html:em>Producer</html:em> represents one
or more sources of data, which it outputs as a stream.  The <html:em>Filter</html:em>
stages convert the input stream to an output stream, perhaps consuming several
input items to yield a single output item.  The <html:em>Consumer</html:em> takes as many
elements as necessary.</html:p>
            <html:p>The Consumer drives the pipeline: nothing is computed except in response to
its demand for an additional datum.  Execution of the Filter stages is
interleaved as required for the computation to go through.  The programmer
sets up the data dependencies but has no clear idea of what happens when.  We
have the illusion of concurrent computation.</html:p>
            <html:p>The Unix operating system provides similar ideas through its <html:em>pipes</html:em> that
link processes together.  In OCaml, we can model pipelines using <html:em>lazy lists</html:em>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/</fr:uri>
            <fr:display-uri>focs-lazy-lists</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-lazy-lists/</fr:route>
            <fr:title text="Lazy Lists (or Streams)">Lazy Lists (or Streams)</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Lists of possibly <html:em>infinite</html:em> length</html:li>
  <html:li>Elements <html:em>computed upon demand</html:em></html:li>
  <html:li><html:em>Avoids waste</html:em> if there are many solutions</html:li>
  <html:li><html:em>Infinite</html:em> values are a useful abstraction</html:li></html:ul>
            <html:p>In OCaml, we can implement laziness by <html:em>delaying evaluation</html:em> of the tail of
the list.</html:p>
            <html:p>Lazy lists have practical uses.  Some algorithms, like <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>, can
yield many solutions when only a few are required.  Sometimes the original
problem concerns infinite series: with lazy lists, we can pretend they really
exist!</html:p>
            <html:p>We are now dealing with <html:em>infinite</html:em> (or at least unbounded) computations.
A potentially infinite source of data is processed one element at a time, upon
demand.  Such programs are harder to understand than terminating ones and have
more ways of going wrong.</html:p>
            <html:p>Some purely functional languages, such as Haskell, use lazy evaluation
everywhere.  Even the if-then-else construct can be a function, and all lists
are lazy.  In OCaml, we can declare a type of lists such that evaluation of the
tail does not occur until demanded.  <html:em>Delayed</html:em> evaluation is weaker than
<html:em>lazy</html:em> evaluation, but it is good enough for our purposes and often the
best compromise for performance and memory usage.</html:p>
            <html:p>The traditional word “stream” is reserved in OCaml parlance for
input/output channels.  Let us call lazy lists <html:em>sequences</html:em> instead.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-ocaml/</fr:uri>
            <fr:display-uri>focs-lazy-ocaml</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-lazy-ocaml/</fr:route>
            <fr:title text="Lazy Lists in OCaml">Lazy Lists in OCaml</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>The empty tuple <html:code>()</html:code> and its <html:em>type</html:em> <html:code>unit</html:code></html:li>
  <html:li>Delayed version of <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:code>fun () -&gt; E</html:code></html:li></html:ul>
            <html:pre><![CDATA[# type 'a seq =
  | Nil
  | Cons of 'a * (unit -> 'a seq)
type 'a seq = Nil | Cons of 'a * (unit -> 'a seq)
# let head (Cons (x, _)) = x
Line 1, characters 10-27:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val head : 'a seq -> 'a = <fun>
# let tail (Cons (_, xf)) = xf ()
Line 1, characters 10-32:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val tail : 'a seq -> 'a seq = <fun>]]></html:pre>
            <html:p><fr:tex display="inline"><![CDATA[\tt  Cons(x, xf)]]></fr:tex> has <html:em>head</html:em> <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <html:em>tail function</html:em> <fr:tex display="inline"><![CDATA[xf]]></fr:tex></html:p>
            <html:p>The primitive OCaml type <html:code>unit</html:code> has one element, which is
written <html:code>()</html:code>.  This element may be regarded as a 0-tuple, and
<html:code>unit</html:code> as the nullary Cartesian product.  (Think of the connection
between multiplication and the number 1.)</html:p>
            <html:p>The empty tuple serves as a placeholder in situations where no information is
required.  It may:</html:p>
            <html:ul><html:li>appear in a data structure.  For example, a <html:code>unit</html:code>-valued <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">dictionary</fr:link> represents a set of keys.</html:li>
  <html:li>be the argument of a function, where its effect is to <html:em>delay evaluation</html:em>.</html:li>
  <html:li>be the argument or result of a procedure. (see the <fr:link href="/~avsm2/fcs/focs-procedural-programming/" title="Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/" display-uri="focs-procedural-programming" type="local">Procedural Programming section</fr:link>)</html:li></html:ul>
            <html:p>The empty tuple, like all tuples, is a constructor and is allowed in patterns;
for example: <html:code>let f () = ...</html:code></html:p>
            <html:p>In particular <fr:tex display="inline"><![CDATA[\tt  fun \, () \rightarrow  E]]></fr:tex> is the function that takes an argument of
type <html:code>unit</html:code> and returns the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as its result.  Expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>
is not evaluated until the function is called, even though the only possible
argument is <html:code>()</html:code>.  The function simply delays the evaluation of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/</fr:uri>
            <fr:display-uri>focs-infinite-sequence</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-infinite-sequence/</fr:route>
            <fr:title text="The Infinite Sequence: k, k+1, k+2, …">The Infinite Sequence: <fr:tex display="inline"><![CDATA[k]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+1]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+2]]></fr:tex>, …</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec from k = Cons (k, fun () -> from (k+1))
val from : int -> int seq = <fun>
# let it = from 1
val it : int seq = Cons (1, <fun>)
# let it = tail it
val it : int seq = Cons (2, <fun>)
# let it = tail it
val it : int seq = Cons (3, <fun>)]]></html:pre>
            <html:p>Function <html:code>from</html:code> constructs the infinite sequence of integers starting
from <fr:tex display="inline"><![CDATA[k]]></fr:tex>.  Execution terminates because of the <html:code>fun</html:code> enclosing the
recursive call.  OCaml displays the tail of a sequence as <html:code>fun</html:code>, which
stands for some function value.  Each call to <html:code>tail</html:code> generates the next
sequence element.  We could do this forever.</html:p>
            <html:p>This example is of little practical value because the cost of computing a
sequence element will be dominated by that of creating the dummy function.
<fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">Lazy lists</fr:link> tend to have high overheads.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/</fr:uri>
            <fr:display-uri>focs-seq-consume</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-seq-consume/</fr:route>
            <fr:title text="Consuming a Sequence">Consuming a Sequence</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec get n s =
    match n, s with
    | 0, _            -> []
    | n, Nil          -> []
    | n, Cons (x, xf) -> x :: get (n-1) (xf ())
val get : int -> 'a seq -> 'a list = <fun>]]></html:pre>
            <html:p>The above code gets the first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements as a list.
<html:code>xf ()</html:code> <html:em>forces</html:em> evaluation.</html:p>
            <html:p>The function <html:code>get</html:code> converts a sequence to a list.  It takes the
first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements; it takes all of them if <fr:tex display="inline"><![CDATA[n<0]]></fr:tex>, which can terminate only if
the sequence is finite.</html:p>
            <html:p>In the last line of <html:code>get</html:code>, the expression <html:code>xf()</html:code> calls the tail
function, demanding evaluation of the next element.  This operation is called
<html:em>forcing</html:em> the sequence.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-evaluation/</fr:uri>
            <fr:display-uri>focs-seq-evaluation</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-seq-evaluation/</fr:route>
            <fr:title text="Sample Evaluation">Sample Evaluation</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tex display="block"><![CDATA[
\begin {aligned}
\tt  get(2,\, from \; 6) \\
\tt  get(2,\, Cons(6, fun \; () \rightarrow  from \; (6+1))) \\
\tt  6 :: get(1,\, from \; (6+1)) \\
\tt  6 :: get(1,\, Cons \; (7,\, fun \; () \rightarrow  from \; (7+1))) \\
\tt  6 :: 7 :: get(0,\, Cons \; (8,\, fun \; () \rightarrow  from \; (8+1))) \\
\tt  6 :: 7 :: [] \\
\tt  [6; 7]
\end {aligned}
]]></fr:tex>
            <html:p>Here we ask for two elements of the infinite sequence.  In fact, three
elements are computed: 6, 7 and 8.  Our implementation is slightly too eager.
A more complicated <html:code>type</html:code> declaration could avoid this problem.
Another problem is that if one repeatedly examines some particular list
element using forcing, that element is repeatedly evaluated.  In a lazy
programming language, the result of the first evaluation would be stored for
later reference.  To get the same effect in OCaml requires the use of
<fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">references</fr:link>.</html:p>
            <html:p>We should be grateful that the potentially infinite computation is kept
finite.  The tail of the original sequence even contains the unevaluated
expression 6+1.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-append/</fr:uri>
            <fr:display-uri>focs-seq-append</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-seq-append/</fr:route>
            <fr:title text="Joining Two Sequences">Joining Two Sequences</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec appendq xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons(x, fun () -> appendq (xf ()) yq)
val appendq : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
            <html:p>A more fair alternative:</html:p>
            <html:pre><![CDATA[# let rec interleave xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons (x, fun () -> interleave yq (xf ()))
val interleave : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
            <html:p>Most list functions and <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> have analogues on sequences, but strange
things can happen.  Can an infinite list be reversed?</html:p>
            <html:p>Function <html:code>appendq</html:code> is precisely the same idea as <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>
from the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">Lists lecture</fr:link>; it concatenates two sequences.  If the first
argument is infinite, then <html:code>appendq</html:code> never gets to its second argument,
which is lost.  Concatenation of infinite sequences is not terribly
interesting.</html:p>
            <html:p>The function <html:code>interleave</html:code> avoids this problem by exchanging the two
arguments in each recursive call.  It combines the two <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, losing no
elements.  Interleaving is the right way to combine two potentially infinite
information sources into one.</html:p>
            <html:p>In both function declarations, observe that each <html:code>xf ()</html:code> is enclosed
within a <fr:tex display="inline"><![CDATA[{\tt  fun () \rightarrow  \ldots }]]></fr:tex>.  Each <html:em>force</html:em> is enclosed within a
<html:em>delay</html:em>.  This practice makes the functions lazy.  A force not enclosed
in a delay, as in <fr:link href="/~avsm2/fcs/focs-seq-consume/" title="Consuming a Sequence" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/" display-uri="focs-seq-consume" type="local"><html:code>get</html:code></fr:link> above, runs the risk of evaluating the sequence
in full.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-functionals/</fr:uri>
            <fr:display-uri>focs-seq-functionals</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-seq-functionals/</fr:route>
            <fr:title text="Functionals for Lazy Lists">Functionals for Lazy Lists</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Filtering <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>:</html:p>
            <html:pre><![CDATA[# let rec filterq p = function
  | Nil -> Nil
  | Cons (x, xf) ->
      if p x then
        Cons (x, fun () -> filterq p (xf ()))
      else
        filterq p (xf ())
val filterq : ('a -> bool) -> 'a seq -> 'a seq = <fun>]]></html:pre>
            <html:p>The infinite sequence <fr:tex display="inline"><![CDATA[x]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(x)]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(f(x))]]></fr:tex>, …</html:p>
            <html:pre><![CDATA[# let rec iterates f x =
    Cons (x, fun () -> iterates f (f x))
val iterates : ('a -> 'a) -> 'a -> 'a seq = <fun>]]></html:pre>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>filterq</html:code> demands elements of <html:code>xq</html:code> until it finds
one satisfying <html:code>p</html:code>.  (Recall <fr:link href="/~avsm2/fcs/focs-predicate-functionals/" title="List Functionals for Predicates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/" display-uri="focs-predicate-functionals" type="local"><html:code>filter</html:code></fr:link>, the analogous operation for ordinary lists.)  It
contains a <html:em>force</html:em> not protected by a <html:em>delay</html:em>.  If <html:code>xq</html:code> is
infinite and contains no satisfactory element, then <html:code>filtering</html:code> runs
forever.</html:p>
            <html:p>The functional <html:code>iterates</html:code> generalises <fr:link href="/~avsm2/fcs/focs-infinite-sequence/" title="The Infinite Sequence: k, k+1, k+2, …" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/" display-uri="focs-infinite-sequence" type="local"><html:code>from</html:code></fr:link>.  It creates the
next element not by adding one but by calling the function <html:code>f</html:code>.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-numerical/</fr:uri>
            <fr:display-uri>focs-seq-numerical</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-seq-numerical/</fr:route>
            <fr:title text="Numerical Computations on Infinite Sequences">Numerical Computations on Infinite Sequences</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let next a x = (a /. x +. x) /. 2.0
val next : float -> float -> float = <fun>]]></html:pre>
            <html:p>Close enough?</html:p>
            <html:pre><![CDATA[# let rec within eps = function
  | Cons (x, xf) ->
      match xf () with
      | Cons (y, yf) ->
          if abs_float (x -. y) <= eps then y
          else within eps (Cons (y, yf))
Lines 3-6, characters 7-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
Lines 1-6, characters 22-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val within : float -> float seq -> float = <fun>]]></html:pre>
            <html:p>Square Roots:</html:p>
            <html:pre><![CDATA[# let root a = within 1e-6 (iterates (next a) 1.0)
val root : float -> float = <fun>]]></html:pre>
            <html:p>The <html:em>Newton-Raphson method</html:em> is widely used for computing square roots.
The infinite series <fr:tex display="inline"><![CDATA[x_0, (a/x_0+x_0)/2, \ldots {}]]></fr:tex> converges rapidly to <fr:tex display="inline"><![CDATA[\sqrt {a}]]></fr:tex>.
The initial approximation, <fr:tex display="inline"><![CDATA[x_0]]></fr:tex>, is typically retrieved from a table, and is accurate enough
that only a few iterations of the method are necessary.
Calling <html:code>iterates (next a) x0</html:code> generates the <html:em>infinite series</html:em> of
approximations to the square root of <fr:tex display="inline"><![CDATA[a]]></fr:tex> using the Newton-Raphson method.
To compute <fr:tex display="inline"><![CDATA[\sqrt 2]]></fr:tex>, the resulting series begins 1, 1.5, 1.41667, 1.4142157, 1.414213562, …,
and this last figure is already accurate to 10 significant digits!</html:p>
            <html:p>Function <html:code>within</html:code> searches down the <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy list</fr:link> for two points whose
difference is less than <html:code>eps</html:code>.  It tests their absolute difference.
Relative difference and other “close enough” tests can be coded.  Such
components can be used to implement other numerical functions directly as
functions over sequences.  The point is to build programs from small,
interchangeable parts.</html:p>
            <html:p>Function <html:code>root</html:code> uses <html:code>within</html:code>, <html:code>iterates</html:code> and <html:code>next</html:code> to
to apply Newton-Raphson with a tolerance of <fr:tex display="inline"><![CDATA[10^{-6}]]></fr:tex>
and a (poor) initial approximation of 1.0.</html:p>
            <html:pre><![CDATA[# root 2.0;;
- : float = 1.41421356237309492]]></html:pre>
            <html:p>This treatment of numerical computation has received some attention in the
research literature; a recurring example is Richardson extrapolation.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/</fr:uri>
            <fr:display-uri>focs-ex-9</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-9/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-1/</fr:uri>
                <fr:display-uri>focs-ex-9-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-1/</fr:route>
                <fr:title text="A map for sequences">A map for sequences</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an analogue of <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> for sequences.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-2/</fr:uri>
                <fr:display-uri>focs-ex-9-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-2/</fr:route>
                <fr:title text="Concatenating infinite sequences">Concatenating infinite sequences</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the list function <html:code>concat</html:code>, which concatenates a list of lists to form a single list. Can
it be generalised to concatenate a sequence of sequences? What can go wrong?</html:p>
                <html:pre><![CDATA[let rec concat = function
| [] -> []
| l::ls -> l @ concat ls]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-3/</fr:uri>
                <fr:display-uri>focs-ex-9-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-3/</fr:route>
                <fr:title text="Making change lazily">Making change lazily</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">make change</fr:link> using <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, delivering the sequence of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">all possible ways of
making change</fr:link>. Using sequences allows us to compute solutions one at a time when there exists an
astronomical number. Represent lists of coins using ordinary lists. (<html:em>Hint</html:em>: to  benefit from
laziness you may need to pass around the sequence of alternative solutions as a function of type
<html:code>unit -&gt; (int list) seq</html:code>.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-4/</fr:uri>
                <fr:display-uri>focs-ex-9-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-4/</fr:route>
                <fr:title text="Lazy binary trees">Lazy binary trees</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A <html:em>lazy binary tree</html:em> is either empty or is a branch containing a label and two lazy <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>,
possibly to infinite depth. Present an OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> to represent lazy binary trees, along with a
function that accepts a lazy binary tree and produces a lazy list that contains all of the tree’s
labels. (Taken from the exam question 2008 Paper 1 Question 5.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-5/</fr:uri>
                <fr:display-uri>focs-ex-9-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-5/</fr:route>
                <fr:title text="All lists of zeroes and ones">All lists of zeroes and ones</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code the lazy list whose elements are all ordinary lists of zeroes and ones, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 1]; [1; 0]; [1; 1]; [0; 0; 0]; </html:code>….  (Taken from the exam question
2003 Paper 1 Question 5.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-6/</fr:uri>
                <fr:display-uri>focs-ex-9-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-6/</fr:route>
                <fr:title text="Enumerating palindromes">Enumerating palindromes</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>(Continuing the previous exercise.)
A <html:em>palindrome</html:em> is a list that equals its own reverse. Code the lazy list whose elements are all
palindromes of 0s and 1s, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 0; 0]; [0; 1; 0]; [1; 1]; [1; 0; 1]; [1; 1; 1]; [0; 0; 0; 0]; </html:code>, …. You
may take the reversal function <html:code>List.rev</html:code> as given.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queues/</fr:uri>
        <fr:display-uri>focs-queues</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-queues/</fr:route>
        <fr:title text="Queues and Search Strategies">Queues and Search Strategies</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/</fr:uri>
            <fr:display-uri>focs-bfs-dfs</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bfs-dfs/</fr:route>
            <fr:title text="Breadth-First v Depth-First Tree Traversal">Breadth-First v Depth-First Tree Traversal</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>binary trees as <html:em>decision trees</html:em></html:li>
  <html:li>look for <html:em>solution nodes</html:em>
    <html:ul><html:li>Depth-first: search one subtree in full before moving on</html:li>
      <html:li>Breadth-first: search all nodes at level <fr:tex display="inline"><![CDATA[k]]></fr:tex> before moving to <fr:tex display="inline"><![CDATA[k+1]]></fr:tex></html:li></html:ul></html:li>
  <html:li>finds <html:em>all</html:em> solutions — nearest first!</html:li></html:ul>
            <html:p><fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">Preorder, inorder and postorder tree traversals</fr:link> all have something in common:
they are depth-first.  At each node, the left subtree is entirely
traversed before the right subtree.  Depth-first traversals are easy to code
and can be efficient, but they are ill-suited for some problems.</html:p>
            <html:p>Suppose the tree represents the possible moves in a puzzle, and the purpose
of the traversal is to search for a node containing a solution.  Then a
depth-first traversal may find one solution node deep in the left subtree,
when another solution is at the very top of the right subtree.  Often we
want the shortest path to a solution.</html:p>
            <html:p>Suppose the tree is <html:em>infinite</html:em> or simply extremely large.  Depth-first search
is almost useless with such trees, for if the left subtree is infinite then the
search will never reach the right subtree.  OCaml can represent infinite trees by
the means discussed in the <fr:link href="/~avsm2/fcs/focs-sequences/" title="Sequences, or Lazy Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sequences/" display-uri="focs-sequences" type="local">lecture on laziness</fr:link>. Another tree representation (suitable
for solving solitaire, for example) is by a function <html:code>next : pos -&gt; pos list</html:code>,
which maps a board position to a list of the positions possible after
the next move.  For simplicity, the examples below use the OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>
<fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local"><html:code>tree</html:code></fr:link>, which has only finite trees.</html:p>
            <html:p>A <html:em>breadth-first</html:em> traversal explores the nodes horizontally rather than
vertically.  When visiting a node, it does not traverse the subtrees until
it has visited all other nodes at the current depth.  This is easily
implemented by keeping a list of trees to visit.  Initially, this list
consists of one element: the entire tree.  Each iteration removes a tree
from the head of the list and adds its subtrees after the end of the
list.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/</fr:uri>
            <fr:display-uri>focs-bfs-append</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bfs-append/</fr:route>
            <fr:title text="Breadth-First Tree Traversal — Using Append">Breadth-First Tree Traversal — Using Append</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec nbreadth = function
  | [] -> []
  | Lf :: ts -> nbreadth ts
  | Br (v, t, u) :: ts ->
      v :: nbreadth (ts @ [t; u])
val nbreadth : 'a tree list -> 'a list = <fun>]]></html:pre>
            <html:p>Keeps an <html:em>enormous queue</html:em> of nodes of search, and is a wasteful use of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.</html:p>
            <html:p>Breadth-first search can be inefficient, this naive implementation especially
so.  When the search is at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> of the tree, the list contains all the
remaining trees at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex>, followed by the subtrees (all at depth <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>) of
the trees that have already been visited.  At depth 10, the list could already
contain 1024 elements.  It requires a lot of space, and aggravates this with a
gross misuse of append.  Evaluating <html:code>ts@[t, u]</html:code> copies the long list
<html:code>ts</html:code> just to insert two elements.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/</fr:uri>
            <fr:display-uri>focs-queue-adt</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-queue-adt/</fr:route>
            <fr:title text="An Abstract Data Type: Queues">An Abstract Data Type: Queues</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li><html:code>qempty</html:code> is the <html:em>empty queue</html:em></html:li>
  <html:li><html:code>qnull</html:code> <html:em>tests</html:em> whether a queue is empty</html:li>
  <html:li><html:code>qhd</html:code> <html:em>returns</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>deq</html:code> <html:em>discards</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>enq</html:code> <html:em>adds</html:em> an element at the <html:em>end</html:em> of a queue</html:li></html:ul>
            <html:p>Breadth-first search becomes much faster if we replace the lists by
<html:em>queues</html:em>.  A queue represents a sequence, allowing elements to be taken
from the head and added to the tail.  This is a First-In-First-Out (FIFO)
discipline: the item next to be removed is the one that has been in the queue
for the longest time.  Lists can implement queues, but <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link> is a poor means
of adding elements to the tail.</html:p>
            <html:p>Our <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional arrays</fr:link> are suitable, provided we
augment them with a function to delete the first array element.  (See <html:em>ML
  for the Working Programmer</html:em> page 156.)  Each operation would take <fr:tex display="inline"><![CDATA[O(\log 
n)]]></fr:tex> time for a queue of length <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
            <html:p>We shall describe a representation of queues that is purely functional, based
upon lists, and efficient.  Operations take <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> time when “amortized”:
averaged over the lifetime of a queue.</html:p>
            <html:p>A conventional programming technique is to represent a queue by an array.  Two
indices point to the front and back of the queue, which may wrap around the
end of the array.  The coding is somewhat tricky.  Worse, the length of the
queue must be given a fixed upper bound.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues-idea/</fr:uri>
            <fr:display-uri>focs-functional-queues-idea</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-functional-queues-idea/</fr:route>
            <fr:title text="Efficient Functional Queues: Idea">Efficient Functional Queues: Idea</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Represent the queue <fr:tex display="inline"><![CDATA[x_1\; x_2\; \ldots \; x_m\; y_n\; \ldots \; y_1]]></fr:tex> by any <html:em>pair of lists</html:em>
    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \; [y_1,y_2,\ldots ,y_n])]]></fr:tex></html:li>
  <html:li>Add new items to the <html:em>rear list</html:em></html:li>
  <html:li>Remove items from <html:em>front list</html:em> and if empty move <html:em>rear</html:em> to <html:em>front</html:em></html:li>
  <html:li><html:em>Amortized</html:em> time per operation is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
            <html:p>Queues require efficient access at both ends: at the front, for removal, and
at the back, for insertion.  Ideally, access should take constant time,
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.  It may appear that lists cannot provide such access.  If
<html:code>enq(q, x)</html:code> performs <html:code>q@[x]</html:code>, then this operation will be <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  We
could represent queues by reversed lists, implementing <html:code>enq(q, x)</html:code> by
<html:code>x::q</html:code>, but then the <html:code>deq</html:code> and <html:code>qhd</html:code> operations would be
<fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Linear time is intolerable: a series of <fr:tex display="inline"><![CDATA[n]]></fr:tex> queue operations
could then require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time.</html:p>
            <html:p>The solution is to represent a queue by a pair of lists, where</html:p>
            <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \, [y_1,y_2,\ldots ,y_n])]]></fr:tex>
            <html:p>represents the queue <fr:tex display="inline"><![CDATA[x_1 x_2 \ldots  x_m y_n \ldots  y_1]]></fr:tex>.</html:p>
            <html:p>The front part of the queue is stored in order, and the rear part is stored in
reverse order.  The <html:code>enq</html:code> operation adds elements to the rear part
using cons, since this list is reversed; thus, <html:code>enq</html:code> takes constant
time.  The <html:code>deq</html:code> and <html:code>qhd</html:code> operations look at the front part,
which normally takes constant time, since this list is stored in order.  But
sometimes <html:code>deq</html:code> removes the last element from the front part; when this
happens, it reverses the rear part, which becomes the new front part.</html:p>
            <html:p><html:em>Amortized</html:em> time refers to the cost per operation averaged over the
lifetime of any complete execution.  Even for the worst possible execution,
the average cost per operation turns out to be constant; see the analysis
below.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/</fr:uri>
            <fr:display-uri>focs-functional-queues</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-functional-queues/</fr:route>
            <fr:title text="Efficient Functional Queues: Code">Efficient Functional Queues: Code</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# type 'a queue =
  | Q of 'a list * 'a list
type 'a queue = Q of 'a list * 'a list
# let norm = function
  | Q ([], tls) -> Q (List.rev tls, [])
  | q -> q
val norm : 'a queue -> 'a queue = <fun>
# let qnull = function
  | Q ([], []) -> true
  | _ -> false
val qnull : 'a queue -> bool = <fun>
# let enq (Q (hds, tls)) x = norm (Q (hds, x::tls))
val enq : 'a queue -> 'a -> 'a queue = <fun>
# exception Empty
exception Empty
# let deq = function
  | Q (x::hds, tls) -> norm (Q (hds, tls))
  | _ -> raise Empty
val deq : 'a queue -> 'a queue = <fun>
# let qempty = Q ([], [])
val qempty : 'a queue = Q ([], [])
# let qhd = function
  | Q (x::_, _) -> x
  | _ -> raise Empty
val qhd : 'a queue -> 'a = <fun>]]></html:pre>
            <html:p>The <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> of queues prevents confusion with other pairs of lists.  The empty
queue has both parts empty.</html:p>
            <html:p>The function <html:code>norm</html:code> puts a queue into normal form, ensuring that the front part
is never empty unless the entire queue is empty.  Functions <html:code>deq</html:code> and <html:code>enq</html:code>
call <html:code>norm</html:code> to normalise their result.</html:p>
            <html:p>Because queues are in normal form, their head is certain to be in their
front part, so <html:code>qhd</html:code> looks there.</html:p>
            <html:p>Let us analyse the cost of an execution comprising (in any possible order) <fr:tex display="inline"><![CDATA[n]]></fr:tex>
<html:code>enq</html:code> operations and <fr:tex display="inline"><![CDATA[n]]></fr:tex> <html:code>deq</html:code> operations, starting with an
empty queue.  Each <html:code>enq</html:code> operation will perform one cons, adding an
element to the rear part.  Since the final queue must be empty, each element
of the rear part gets transferred to the front part.  The corresponding
reversals perform one cons per element.  Thus, the total cost of the series of
queue operations is <fr:tex display="inline"><![CDATA[2n]]></fr:tex> cons operations, an average of 2 per operation.  The
amortized time is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
            <html:p>There is a catch.  The conses need not be distributed evenly; reversing a long
list could take up to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> of them.  Unpredictable delays make the approach
unsuitable for <html:em>real-time programming</html:em> where deadlines must be met.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/</fr:uri>
            <fr:display-uri>focs-bfs-queues</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bfs-queues/</fr:route>
            <fr:title text="Breadth-First Tree Traversal — Using Queues">Breadth-First Tree Traversal — Using Queues</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let rec breadth q =
    if qnull q then []
    else
      match qhd q with
      | Lf -> breadth (deq q)
      | Br (v, t, u) -> v :: breadth (enq (enq (deq q) t) u)
val breadth : 'a tree queue -> 'a list = <fun>]]></html:pre>
            <html:p>This function implements the same algorithm as <fr:link href="/~avsm2/fcs/focs-bfs-append/" title="Breadth-First Tree Traversal — Using Append" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/" display-uri="focs-bfs-append" type="local"><html:code>nbreadth</html:code></fr:link> but uses a different
data structure.  It represents queues using type <fr:link href="/~avsm2/fcs/focs-functional-queues/" title="Efficient Functional Queues: Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/" display-uri="focs-functional-queues" type="local"><html:code>queue</html:code></fr:link> instead of type
<html:code>list</html:code>.</html:p>
            <html:p>To compare their efficiency, I applied both functions to the full binary tree
of depth 12, which contains 4095 labels.  The function <html:code>nbreadth</html:code> took 30
seconds while <html:code>breadth</html:code> took only 0.15 seconds: faster by a factor of 200.</html:p>
            <html:p>For larger trees, the speedup would be greater.  Choosing the right data
structure pays handsomely.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/</fr:uri>
            <fr:display-uri>focs-iterative-deepening</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-iterative-deepening/</fr:route>
            <fr:title text="Iterative deepening: Another Exhaustive Search">Iterative deepening: Another Exhaustive Search</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Breadth-first search examines <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> nodes:
    <fr:tex display="block"><![CDATA[1 + b + \cdots  + b^d = {b^{d+1}-1 \over  b-1}
  \qquad  \begin {array}[c]{rl}
            b & {} = \hbox {branching factor}\\
            d & {} = \hbox {depth}
          \end {array}]]></fr:tex></html:li>
  <html:li>Recompute nodes at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> instead of storing them</html:li>
  <html:li>Time factor is <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>; complexity is still <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex></html:li>
  <html:li>Space required at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> drops from <fr:tex display="inline"><![CDATA[b^d]]></fr:tex> to <fr:tex display="inline"><![CDATA[d]]></fr:tex></html:li></html:ul>
            <html:p>Breadth-first search is not practical for infinite trees: it uses too much
space. Large parts of the tree have to be stored.
Consider the slightly more general problem of searching trees whose
branching factor is <fr:tex display="inline"><![CDATA[b]]></fr:tex> (for binary trees, <fr:tex display="inline"><![CDATA[b=2]]></fr:tex>).  Then breadth-first search
to depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> examines <fr:tex display="inline"><![CDATA[(b^{d+1}-1)/(b-1)]]></fr:tex> nodes, which is <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>, ignoring
the constant factor of <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex>.  Since all nodes that are examined are also
stored, the space and time requirements are both <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.</html:p>
            <html:p><html:em>Depth-first iterative deepening</html:em> combines the space efficiency of
depth-first with the “nearest-first” property of breadth-first search.  It
performs repeated depth-first searches with increasing depth bounds, each time
discarding the result of the previous search.  Thus it searches to depth 1,
then to depth 2, and so on until it finds a solution.  We can afford to
discard previous results because the number of nodes is growing exponentially.
There are <fr:tex display="inline"><![CDATA[b^{d+1}]]></fr:tex> nodes at level <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>; if <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex>, this number actually
exceeds the total number of nodes of all previous levels put together, namely
<fr:tex display="inline"><![CDATA[(b^{d+1}-1) / (b-1)]]></fr:tex>.</html:p>
            <html:p><fr:link href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288" type="external">Korf shows</fr:link> that the time needed for iterative deepening to reach
depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> is only <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> times that for breadth-first search, if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>.
This is a constant factor; both algorithms have the same time complexity,
<fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.  In typical applications where <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex> the extra factor of
<fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> is quite tolerable.  The reduction in the space requirement is
exponential, from <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> for breadth-first to <fr:tex display="inline"><![CDATA[O(d)]]></fr:tex> for iterative
deepening. Of course, this assumes that the tree itself is not stored in memory.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/</fr:uri>
            <fr:display-uri>focs-stacks</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-stacks/</fr:route>
            <fr:title text="Another Abstract Data Type: Stacks">Another Abstract Data Type: Stacks</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li><html:code>empty</html:code> is the <html:em>empty stack</html:em></html:li>
  <html:li><html:code>null</html:code> tests whether a stack is empty</html:li>
  <html:li><html:code>top</html:code> returns the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>pop</html:code> discards the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>push</html:code> adds an element at the <html:em>top</html:em> of a stack</html:li></html:ul>
            <html:p>A <html:em>stack</html:em> is a sequence such that items can be added or removed from the head
only.  A stack obeys a Last-In-First-Out (LIFO) discipline: the item next to be
removed is the one that has been in the queue for the <html:em>shortest</html:em> time.  Lists
can easily implement stacks because both <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> affect the head.  But
unlike lists, stacks are often regarded as an imperative data structure: the
effect of <html:code>push</html:code> or <html:code>pop</html:code> is to change an existing stack, not return a new one.</html:p>
            <html:p>In conventional programming languages, a stack is often implemented by storing
the elements in an array, using a variable (the “stack pointer”) to count them.
Most language processors keep track of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function calls</fr:link> using an
internal stack.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-search-methods/</fr:uri>
            <fr:display-uri>focs-search-methods</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-search-methods/</fr:route>
            <fr:title text="A Survey of Search Methods">A Survey of Search Methods</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Depth-first: use a <html:em>stack</html:em>  (efficient but incomplete)</html:li>
  <html:li>Breadth-first: use a <html:em>queue</html:em> (uses too much space!)</html:li>
  <html:li>Iterative deepening: use depth-first to get benefits of breadth-first (trades time for space)</html:li>
  <html:li>Best-first: use a <html:em>priority queue</html:em> (heuristic search)</html:li></html:ul>
            <html:p>The data structure determines the search!</html:p>
            <html:p>Search procedures can be classified by the data structure used to store
pending subtrees.  Depth-first search stores them on a stack, which is
implicit in functions like <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link>, but can be made explicit.
Breadth-first search stores such nodes in a queue.</html:p>
            <html:p>An important variation is to store the nodes in a priority queue, which
is an ordered sequence.  The priority queue applies some sort of ranking
function to the nodes, placing higher-ranked nodes before lower-ranked ones.
The ranking function typically estimates the distance from the node to a
solution.  If the estimate is good, the solution is located swiftly.  This
method is called best-first search.</html:p>
            <html:p>The priority queue can be kept as a sorted list, although this is slow.
<fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary search trees</fr:link> would be much better on average, and fancier data
structures improve matters further.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/</fr:uri>
            <fr:display-uri>focs-ex-10</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-10/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-1/</fr:uri>
                <fr:display-uri>focs-ex-10-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-1/</fr:route>
                <fr:title text="Tree-based queues">Tree-based queues</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Suppose that we have an implementation of queues, based on <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>, such that each operation
takes logarithmic time in the worst case. Outline the advantages and drawbacks of such an
implementation compared with one presented above.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-2/</fr:uri>
                <fr:display-uri>focs-ex-10-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-2/</fr:route>
                <fr:title text="Array-based circular queues">Array-based circular queues</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>The traditional way to implement queues uses a fixed-length array. Two indices into the array
indicate the start and end of the queue, which wraps around from the end of the array to the start.
How appropriate is such a data structure for implementing <fr:link href="/~avsm2/fcs/focs-bfs-dfs/" title="Breadth-First v Depth-First Tree Traversal" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/" display-uri="focs-bfs-dfs" type="local">breadth-first search</fr:link>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-3/</fr:uri>
                <fr:display-uri>focs-ex-10-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-3/</fr:route>
                <fr:title text="Rewriting breadth with let">Rewriting breadth with let</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a version of the function <fr:link href="/~avsm2/fcs/focs-bfs-queues/" title="Breadth-First Tree Traversal — Using Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/" display-uri="focs-bfs-queues" type="local"><html:code>breadth</html:code></fr:link> using a nested <html:code>let</html:code> construction rather than
<html:code>match</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-4/</fr:uri>
                <fr:display-uri>focs-ex-10-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-4/</fr:route>
                <fr:title text="Search with a branching factor near one">Search with a branching factor near one</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p><fr:link href="/~avsm2/fcs/focs-iterative-deepening/" title="Iterative deepening: Another Exhaustive Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/" display-uri="focs-iterative-deepening" type="local">Iterative deepening</fr:link> is inappropriate if <fr:tex display="inline"><![CDATA[b\approx 1]]></fr:tex>, where <fr:tex display="inline"><![CDATA[b]]></fr:tex> is the branching factor. What search
strategy is appropriate in this case?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-5/</fr:uri>
                <fr:display-uri>focs-ex-10-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-5/</fr:route>
                <fr:title text="An implicit infinite tree">An implicit infinite tree</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the following OCaml function.</html:p>
                <html:pre><![CDATA[let next n = [2 * n; 2 * n + 1]]]></html:pre>
                <html:p>If we regard it as representing a tree, where the subtrees are computed from the current label, what
tree does <html:code>next 1</html:code> represent?</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false">
      <fr:frontmatter>
        <fr:authors>
          <fr:author>
            <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
          </fr:author>
        </fr:authors>
        <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/</fr:uri>
        <fr:display-uri>focs-procedural</fr:display-uri>
        <fr:route>/~avsm2/fcs/focs-procedural/</fr:route>
        <fr:title text="Elements of Procedural Programming">Elements of Procedural Programming</fr:title>
        <fr:taxon>Lecture</fr:taxon>
        <fr:meta name="external">https://hub.cl.cam.ac.uk/</fr:meta>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/</fr:uri>
            <fr:display-uri>focs-procedural-programming</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-procedural-programming/</fr:route>
            <fr:title text="Procedural Programming">Procedural Programming</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Procedural programs can change the machine state.</html:li>
  <html:li>They can interact with its environment</html:li>
  <html:li>They use control structures like branching, iteration and procedures.</html:li></html:ul>
            <html:p>They use data abstractions of the computer’s memory:</html:p>
            <html:ul><html:li><html:em><fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link></html:em> to memory cells</html:li>
  <html:li><html:em>arrays</html:em> that are blocks of memory cells</html:li>
  <html:li><html:em>linked structures</html:em> such as <html:em>linked lists</html:em></html:li></html:ul>
            <html:p>Procedural programming is programming in the traditional sense of the word.  A
program <html:em>state</html:em> is repeatedly transformed by the execution of
<html:em>commands</html:em> or <html:em>statements</html:em>.  A state change might be local to the
machine and consist of updating a variable or array.  A state change might
consist of sending data to the outside world.  Even reading data counts as a
state change, since this act normally removes the data from the environment.</html:p>
            <html:p>Procedural programming languages provide primitive commands and control
structures for combining them.  The primitive commands include
<html:em>assignment</html:em> for updating variables, and various <html:em>input/output</html:em>
commands for communication.  Control structures include <html:code>if</html:code> and
<html:code>match</html:code> constructs for conditional execution, and repetitive constructs
such as <html:code>while</html:code>.  Programmers can package up their own commands as
<html:em>procedures</html:em> taking arguments.  The need for such “subroutines” was
evident from the earliest days; they represent one of the first
examples of <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstraction</fr:link> in programming languages.</html:p>
            <html:p>OCaml makes no distinction between commands and expressions. OCaml provides built-in
‘functions’ to perform assignment and communication, and these can be used
in the traditional (procedural) style. OCaml programmers often follow a
functional style for most internal computations and use imperative features
mainly for communication with the outside world.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/</fr:uri>
            <fr:display-uri>focs-references</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-references/</fr:route>
            <fr:title text="OCaml Primitives for References">OCaml Primitives for References</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>Effect</html:th></html:tr>
  <html:tr><html:td><html:code>ref E</html:code></html:td><html:td><html:em>create</html:em> a reference with <html:em>initial contents</html:em> = value of <html:code>E</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!P</html:code></html:td><html:td>return <html:em>current contents</html:em> of reference <html:code>P</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>P := E</html:code></html:td><html:td><html:em>update</html:em> contents of <html:code>P</html:code> to value of <html:code>E</html:code></html:td></html:tr>
</html:table>
            <html:p>The above text presents the OCaml primitives, but most languages have analogues of
them, often heavily disguised.  We need a means of creating references (or
allocating storage), getting at the current contents of a reference cell, and
updating that cell.</html:p>
            <html:p>The function <html:code>ref</html:code> creates references (also called
“locations”).  Calling <html:code>ref</html:code> allocates a new location in memory.
Initially, this location holds the value given by
expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
            <html:p>The function <html:code>!</html:code>, when applied to a reference, returns its contents.
This operation is called <html:em>dereferencing</html:em>.  Clearly <html:code>!</html:code> is not a
mathematical function; its result depends upon the store.</html:p>
            <html:p>The assignment <html:code>P:=E</html:code> evaluates expression <fr:tex display="inline"><![CDATA[P]]></fr:tex>, which must return a
reference <fr:tex display="inline"><![CDATA[p]]></fr:tex>, and <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It stores at address <fr:tex display="inline"><![CDATA[p]]></fr:tex> the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.
Syntactically, <html:code>:=</html:code> is a function and <html:code>P:=E</html:code> is an
expression, even though it updates the store.  Like many functions that change
the state, it returns the value <html:code>()</html:code> of type <html:code>unit</html:code>.</html:p>
            <html:p>If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the type of references
to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.  Please do not confuse the type
<html:code>ref</html:code> with the function <html:code>ref</html:code>.  This table of the primitive
functions and their types might be useful:</html:p>
            <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>OCaml Type</html:th></html:tr>
  <html:tr><html:td><html:code>ref</html:code></html:td><html:td><html:code>'a -&gt; 'a ref</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!</html:code></html:td><html:td><html:code>'a ref -&gt; 'a</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>:=</html:code></html:td><html:td><html:code>'a ref -&gt; 'a -&gt; unit</html:code></html:td></html:tr>
</html:table>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-examples/</fr:uri>
            <fr:display-uri>focs-references-examples</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-references-examples/</fr:route>
            <fr:title text="Trying Out References">Trying Out References</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let p = ref 5 (* create a reference *)
val p : int ref = {contents = 5}
# p := !p + 1   (* p now holds value 6 *)
- : unit = ()
# let ps = [ ref 77; p ]
val ps : int ref list = [{contents = 77}; {contents = 6}]
# List.hd ps := 3
- : unit = ()
# ps
- : int ref list = [{contents = 3}; {contents = 6}]]]></html:pre>
            <html:p>The first line declares <html:code>p</html:code> to hold a <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> to an integer,
initially 5.  Its type is <html:code>int ref</html:code>, not just <html:code>int</html:code>, so it
admits assignment.  Assignment never changes <html:code>let</html:code> bindings: they are
<html:em>immutable</html:em>.  The identifier <html:code>p</html:code> will always denote the reference
mentioned in its declaration unless superseded by a new usage of <html:code>p</html:code>.
Only the <html:em>contents</html:em> of the reference is mutable.</html:p>
            <html:p>OCaml displays a reference value as <html:code><![CDATA[{contents=v}]]></html:code>, where value <fr:tex display="inline"><![CDATA[v]]></fr:tex> is the
contents.  This notation is readable but gives us no way of telling whether
two references holding the same value are actually the same reference.  To
display a reference as a machine address has obvious drawbacks!</html:p>
            <html:p>In the first assignment, the expression <html:code>!p</html:code> yields the reference’s
current contents, namely 5.  The assignment changes the contents of <html:code>p</html:code>
to 6.  Most languages do not have an explicit dereferencing operator
(like <html:code>!</html:code>) because of its inconvenience.  Instead, by convention,
occurrences of the reference on the <html:em>left-hand</html:em> side of the <html:code>:=</html:code>
denote locations and those on the <html:em>right-hand</html:em> side denote the contents.
A special ‘address of’ operator may be available to override the convention
and make a reference on the right-hand side to denote a location.  Logically
this is a mess, but it makes programs shorter.</html:p>
            <html:p>The list <html:code>ps</html:code> is declared to hold a new reference (initially
containing 77) as well as <html:code>p</html:code>.  Then the new reference is
updated to hold 3.  The assignment to <html:code>hd ps</html:code> does <html:em>not</html:em>
update <html:code>ps</html:code>, only the contents of a reference in that list.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-commands/</fr:uri>
            <fr:display-uri>focs-commands</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-commands/</fr:route>
            <fr:title text="Commands: Expressions with Effects">Commands: Expressions with Effects</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>Basic commands update <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link>, write to files, etc.</html:li>
  <html:li><fr:tex display="inline"><![CDATA[C_1 ; \ldots  ; C_n]]></fr:tex> causes a series of expressions to be evaluated and returns the value of <fr:tex display="inline"><![CDATA[C_n]]></fr:tex>.</html:li>
  <html:li>A typical command returns the empty tuple: <html:code>()</html:code></html:li>
  <html:li><html:code>if</html:code> <fr:tex display="inline"><![CDATA[B]]></fr:tex> <html:code>then</html:code> <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> <html:code>else</html:code> <fr:tex display="inline"><![CDATA[C_2]]></fr:tex> behaves like the traditional control structure if <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> and <fr:tex display="inline"><![CDATA[C_2]]></fr:tex> have effects.</html:li>
  <html:li>Other OCaml constructs behave naturally with commands, including <html:code>match</html:code> expressions and recursive functions.</html:li></html:ul>
            <html:p>We use the term <html:em>command</html:em> informally to refer to an expression that has an
effect on the state. All expressions denote some value, but they can return
<html:code>()</html:code>, which conveys no actual information.</html:p>
            <html:p>We need a way to execute one command after another.
The construct <fr:tex display="inline"><![CDATA[C_1 ; \ldots  ; C_n]]></fr:tex> evaluates the expressions <fr:tex display="inline"><![CDATA[C_1]]></fr:tex>
to <fr:tex display="inline"><![CDATA[C_n]]></fr:tex> in the order given and returns the value of <fr:tex display="inline"><![CDATA[C_n]]></fr:tex>.  The values
of the other expressions are discarded; their only purpose is to change the
state.</html:p>
            <html:p>Commands may be used with <html:code>if</html:code> and <html:code>match</html:code> much as in conventional languages.
OCaml functions play the role of procedures.</html:p>
            <html:p>Other languages that combine the functional and imperative programming
paradigms include Lisp (and its dialect Scheme), Scala, and even a
systems programming language, BLISS (now long extinct).</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/</fr:uri>
            <fr:display-uri>focs-while</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-while/</fr:route>
            <fr:title text="Iteration: the while command">Iteration: the while command</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let tlopt = function
  | [] -> None
  | _::xs -> Some xs
val tlopt : 'a list -> 'a list option = <fun>
# let length xs =
    let lp  = ref xs in (* list of uncounted elements *)
    let np  = ref 0  in (* accumulated count *)
    let fin = ref false in
    while not !fin do
      match tlopt !lp with
      | None -> fin := true
      | Some xs ->
          lp := xs;
          np := 1 + !np
    done;
    !np (* the final count is returned *)
val length : 'a list -> int = <fun>]]></html:pre>
            <html:p>Once we can change the state, we need to do so repeatedly.  <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">Recursion</fr:link> can
serve this purpose, but having to declare a procedure for every loop is
clumsy, and compilers for conventional languages seldom exploit
<fr:link href="/~avsm2/fcs/focs-recursion-vs-iteration/" title="Recursion vs Iteration" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/" display-uri="focs-recursion-vs-iteration" type="local">tail-recursion</fr:link>.</html:p>
            <html:p>Early programming languages provided little support for repetition.  The
programmer had to set up loops using goto commands, exiting the loop using
another goto controlled by an <html:code>if</html:code>.  Modern languages provide a
confusing jumble of looping constructs, the most fundamental of which is
<html:code>while B do C</html:code>.  The boolean expression <fr:tex display="inline"><![CDATA[B]]></fr:tex> is evaluated,
and if true, command <fr:tex display="inline"><![CDATA[C]]></fr:tex> is executed and the command repeats.  If <fr:tex display="inline"><![CDATA[B]]></fr:tex>
evaluates to false then the <html:code>while</html:code> command terminates, perhaps without
executing <fr:tex display="inline"><![CDATA[C]]></fr:tex> even once.</html:p>
            <html:p>OCaml’s main looping construct is <html:code>while</html:code>, which returns the value <html:code>()</html:code>.  The
function <html:code>length</html:code> declares <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> to hold the list under
examination (<html:code>lp</html:code>) and number of elements counted so far (<html:code>np</html:code>) as well
as whether the end of the list has been reached (the boolean reference <html:code>fin</html:code>).
While the list is non-empty, we skip over one more element (by setting it to
its tail) and count that element.</html:p>
            <html:p>The body of the <html:code>while</html:code> loop first checks to see if the end of the list has
been reached, in which case it sets the <html:code>fin</html:code> variable to true.  If there is a
tail value, then two assignments are executed in sequence.  The <html:code>lp</html:code> reference
is set to the tail of the list, and the <html:code>np</html:code> reference integer is incremented
by one.  When the while loop terminates due to the <html:code>fin</html:code> variable being set to
true, the expression <html:code>!np</html:code> returns the computed length as the function’s
result.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/</fr:uri>
            <fr:display-uri>focs-private-references</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-private-references/</fr:route>
            <fr:title text="Private, Persistent References">Private, Persistent References</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# exception TooMuch of int
exception TooMuch of int
# let makeAccount initBalance =
    let balance = ref initBalance in
    let withdraw amt =
       if amt > !balance then
         raise (TooMuch (amt - !balance))
       else begin
         balance := !balance - amt;
         !balance
       end
    in
    withdraw
val makeAccount : int -> int -> int = <fun>]]></html:pre>
            <html:p>As you may have noticed, OCaml’s programming style looks clumsy compared with
that of languages like C.  OCaml omits the defaults and abbreviations they
provide to shorten programs.  However, OCaml’s explicitness makes it ideal for
teaching the fine points of <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> and arrays.  OCaml’s references are more
flexible than those found in other languages.</html:p>
            <html:p>The function <html:code>makeAccount</html:code> models a bank.  Calling the function with a
specified initial balance creates a new reference <html:code>balance</html:code><![CDATA[)]]> to
maintain the account balance and returns a function (<html:code>withdraw</html:code>) having
sole access to that reference.  Calling <html:code>withdraw</html:code> reduces the balance
by the specified amount and returns the new balance.  You can pay money in by
withdrawing a negative amount.  The <html:code>if</html:code>-construct prevents the account
from going overdrawn, <fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">raising an exception</fr:link>.</html:p>
            <html:p>Look at the <fr:tex display="inline"><![CDATA[\tt  (E_1; E_2)]]></fr:tex> construct in the <html:em>else</html:em> part above.
The first expression updates the account balance and returns the trivial
value ().  The second expression, <html:code>!balance</html:code>, returns the current
balance but does not return the reference itself: that would allow
unauthorised updates.</html:p>
            <html:p>This example is based on one by Dr A C Norman.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bank-accounts/</fr:uri>
            <fr:display-uri>focs-bank-accounts</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-bank-accounts/</fr:route>
            <fr:title text="Two Bank Accounts">Two Bank Accounts</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# let student = makeAccount 500
val student : int -> int = <fun>
# let director = makeAccount 4000000;
val director : int -> int = <fun>
# student 5        (* coach fare *)
- : int = 495
# director 150000  (* Tesla *)
- : int = 3850000
# student 500      (* oh oh *)
Exception: TooMuch 5.]]></html:pre>
            <html:p>Each call to <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>makeAccount</html:code></fr:link> returns a copy of <html:code>withdraw</html:code> holding
a <html:em>fresh</html:em> instance of the <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> <html:code>balance</html:code>.  As with a real bank
pass-book, there is no access to the account balance except via the
corresponding <html:code>withdraw</html:code> function.  If that function is discarded, the
reference cell becomes unreachable; the computer will eventually reclaim it,
just as banks close down dormant accounts.</html:p>
            <html:p>Here we see two people managing their accounts.  For better or worse, neither
can take money from the other.</html:p>
            <html:p>We could generalise <html:code>makeAccount</html:code> to return several functions that
jointly manage information held in shared references.  The functions might be
packaged using OCaml records, which are not discussed in this course.
Most procedural languages do not properly support the concept of private
references, although <html:em>object-oriented</html:em> languages take them as a basic theme.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/</fr:uri>
            <fr:display-uri>focs-array-primitives</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-array-primitives/</fr:route>
            <fr:title text="OCaml Primitives for Arrays">OCaml Primitives for Arrays</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:pre><![CDATA[# [|"a"; "b"; "c"|] (* allocate a fresh string array *)
- : string array = [|"a"; "b"; "c"|]
# Array.make 3 'a'   (* array[3] with cell containing 'a' *)
- : char array = [|'a'; 'a'; 'a'|]
# let aa = Array.init 5 (fun i -> i * 10) (* array[5] initialised to (fun i) *)
val aa : int array = [|0; 10; 20; 30; 40|]
# Array.get aa 3  (* retrieve the 4th cell in the array *)
- : int = 30
# Array.set aa 3 42 (* set the 4th cell's value to 42 *)
- : unit = ()]]></html:pre>
            <html:p>There are many other array operations in the <html:code>Array</html:code> module in the OCaml standard
library.</html:p>
            <html:pre><![CDATA[# Array.make
- : int -> 'a -> 'a array = <fun>
# Array.init
- : int -> (int -> 'a) -> 'a array = <fun>
# Array.get
- : 'a array -> int -> 'a = <fun>
# Array.set
- : 'a array -> int -> 'a -> unit = <fun>]]></html:pre>
            <html:p>OCaml arrays are like <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> that hold several elements instead of one.  The
elements of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element array are designated by the integers from 0
to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.  The <fr:tex display="inline"><![CDATA[i]]></fr:tex>th array element is usually written <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.
If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is a type then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>array</html:code> is the
type of arrays (of any size) with elements from <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.</html:p>
            <html:p>Calling <html:code>Array.init n f</html:code> creates an array of the size specified in <fr:tex display="inline"><![CDATA[n]]></fr:tex>
by function <fr:tex display="inline"><![CDATA[f]]></fr:tex>.  Initially, element <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex> holds the value of <fr:tex display="inline"><![CDATA[f(i)]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.
Like <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local"><html:code>ref</html:code></fr:link>, it allocates mutable storage to hold the specified values.</html:p>
            <html:p>Calling <html:code>Array.get A i</html:code> returns the contents of <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.</html:p>
            <html:p>Calling <html:code>Array.set A i E</html:code> modifies the array <fr:tex display="inline"><![CDATA[A]]></fr:tex> by storing the
value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as the new contents of <fr:tex display="inline"><![CDATA[A[i]]]></fr:tex>; it returns <html:code>()</html:code> as its value.</html:p>
            <html:p>OCaml’s arrays are much safer than C’s. In C, an array is nothing more than an
address indicating the start of a storage area. Nothing indicates the size of
the area.  Therefore C programs are vulnerable to <html:em>buffer overrun attacks:</html:em> an
attacker sends more data than the receiving program expects, overrunning the
area of storage set aside to hold it. The attack eventually overwrites the
program itself, replacing it with code controlled by the attacker.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-examples/</fr:uri>
            <fr:display-uri>focs-array-examples</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-array-examples/</fr:route>
            <fr:title text="Array Examples">Array Examples</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>In the following session, the identifier <html:code>ar</html:code> is bound to an array of 20 elements, which
are initially set to the squares of their subscripts.  The array’s third
element (which actually has subscript 2) is inspected and found to be four. The
second call to <html:code>Array.get</html:code> supplies a subscript that is out of range, so OCaml
rejects it.</html:p>
            <html:pre><![CDATA[# let ar = Array.init 20 (fun i -> i * i)
val ar : int array =
  [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
    289; 324; 361|]
# Array.get ar 2
- : int = 4
# Array.get ar 20
Exception: Invalid_argument "index out of bounds".
# Array.set ar 2 33; ar
- : int array =
[|0; 1; 33; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
  289; 324; 361|]]]></html:pre>
            <html:p>By calling <html:code>Array.set</html:code>, we then modify the element with subscript 2. Note
however that we cannot modify the array’s length. If we outgrow the array, we
have to create a new one, copy the data into it, and then forget the old array.
Typically the new array would be double the size of the old one, so that the
cost of copying is insignificant.</html:p>
            <html:p>OCaml provides numerous operators for modifying, computing over and searching in
arrays. Many are analogous to <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">functions on lists</fr:link>. For example,
<html:code>Array.exists</html:code> takes a boolean-valued function and returns <html:code>true</html:code> if an
array element satisfies it.</html:p>
            <html:pre><![CDATA[# Array.exists (fun i -> i > 200) ar
- : bool = true
# Array.exists (fun i -> i < 0) ar
- : bool = false]]></html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-comparison/</fr:uri>
            <fr:display-uri>focs-references-comparison</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-references-comparison/</fr:route>
            <fr:title text="References: OCaml vs conventional languages">References: OCaml vs conventional languages</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:ul><html:li>We must write <html:code>!p</html:code> to get the <html:em>contents</html:em> of <html:code>p</html:code></html:li>
  <html:li>We write just <html:code>p</html:code> for the <html:em>address</html:em> of <html:code>p</html:code></html:li>
  <html:li>We can store private <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference cells</fr:link> (like <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>balance</html:code></fr:link>) in functions—analogous to elements of <html:em>object-oriented programming</html:em></html:li>
  <html:li>OCaml’s assignment syntax is <fr:tex display="inline"><![CDATA[\tt  V \, := \, E]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[V]]></fr:tex> = <fr:tex display="inline"><![CDATA[E]]></fr:tex></html:li>
  <html:li>OCaml has few control structures: <fr:link href="/~avsm2/fcs/focs-while/" title="Iteration: the while command" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/" display-uri="focs-while" type="local"><html:code>while</html:code></fr:link>, <html:code>match</html:code>, <html:code>if</html:code> and <html:code>for</html:code> (the latter is not covered in this course)</html:li>
  <html:li>OCaml has syntax for updating an array via the <html:code>a.(i) &lt;- v</html:code> syntax which is the same as <fr:link href="/~avsm2/fcs/focs-array-primitives/" title="OCaml Primitives for Arrays" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/" display-uri="focs-array-primitives" type="local"><html:code>Array.set a i v</html:code></fr:link>.</html:li></html:ul>
            <html:p>Conventional syntax for variables and assignments has hardly changed since
Fortran, the first high-level language. In conventional languages,
virtually all variables can be updated.  We declare something like
<html:code>p: int</html:code>, mentioning no reference type even if the language provides
them.  If we do not specify an initial value, we may get whatever bits were
previously at that address.  Illegal values arising from uninitialised
variables can cause errors that are almost impossible to diagnose.</html:p>
            <html:p>Dereferencing operators (like OCaml’s <html:code>!</html:code>) are especially unpopular, because
they clutter the program text. Virtually all programming languages make dereferencing
implicit (that is, automatic).</html:p>
            <html:p>It is generally accepted these days that a two-dimensional array <fr:tex display="inline"><![CDATA[A]]></fr:tex> is nothing
but an array of arrays.  An assignment to such an array is typically written
something like <fr:tex display="inline"><![CDATA[A[i,j] {:=} x]]></fr:tex>; in C, the syntax is <html:code>A[i][j] = x</html:code>. Higher
dimensions are treated analogously.  The corresponding OCaml code can either
declare an array of arrays, or use the <html:code>A.(i)</html:code> syntax to calculate the linear
offset into a single array.</html:p>
            <html:p>You can use the constructs we have learnt to easily create linked (mutable) lists as
an alternative to arrays.</html:p>
            <html:pre><![CDATA[# type 'a mlist =
  | Nil
  | Cons of 'a * 'a mlist ref
type 'a mlist = Nil | Cons of 'a * 'a mlist ref]]></html:pre>
            <html:p>It is worth mentioning that OCaml’s references fully suffice for coding the sort of linked data structures
taught in algorithms courses, and is illustrated in the figure above. The
programming style is a little different from the usual, but the principles are
the same.  OCaml also provides comprehensive input/output primitives for various
types of file and operating system.</html:p>
            <html:p>OCaml’s system of modules include <html:em>structures,</html:em> which can be seen as encapsulated
groups of declarations, and <html:em>signatures,</html:em> which are specifications of
structures listing the name and type of each component.  Finally, there are
<html:em>functors,</html:em> which are analogous to functions that combine a number of argument
structures, and which can be used to plug program components together. These
primitives are useful for managing large programming projects.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false" expanded="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/</fr:uri>
            <fr:display-uri>focs-ex-11</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-ex-11/</fr:route>
            <fr:title text="Exercises">Exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-1/</fr:uri>
                <fr:display-uri>focs-ex-11-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-1/</fr:route>
                <fr:title text="Lists of references">Lists of references</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Comment, with examples, on the differences between an <html:code>int ref list</html:code> and an <html:code>int list ref</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-2/</fr:uri>
                <fr:display-uri>focs-ex-11-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-2/</fr:route>
                <fr:title text="Iterative power with while">Iterative power with while</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a version of function <html:code>power</html:code> (<fr:link href="/~avsm2/fcs/focs-intro/" title="Introduction to Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" type="local">Lecture <fr:contextual-number uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" /></fr:link>) using <html:code>while</html:code> instead of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-3/</fr:uri>
                <fr:display-uri>focs-ex-11-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-3/</fr:route>
                <fr:title text="Effects in a while condition">Effects in a while condition</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What is the effect of <fr:tex display="inline"><![CDATA[\tt  while \, C_1; \; B \, do \, C_2 \, done]]></fr:tex> ?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-4/</fr:uri>
                <fr:display-uri>focs-ex-11-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-4/</fr:route>
                <fr:title text="Exchanging two references">Exchanging two references</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a function to exchange the values of two <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link>, <html:code>xr</html:code> and <html:code>yr</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false" toc="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-5/</fr:uri>
                <fr:display-uri>focs-ex-11-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-5/</fr:route>
                <fr:title text="Matrix operations on arrays">Matrix operations on arrays</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Arrays of multiple dimensions are represented in OCaml by arrays of arrays. Write functions to
(a) create an <fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> identity matrix, given <fr:tex display="inline"><![CDATA[n]]></fr:tex>, and
(b) to <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local">transpose</fr:link> an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix. Identity matrices have the following form:</html:p>
                <fr:tex display="block"><![CDATA[
\left ( {
\begin {array}{cccc}
   1 & 0 &  \cdots   & 0  \\
   0 & 1 &  \cdots   & 0  \\
    \vdots   &  \vdots   &  \ddots   &  \vdots    \\
   0 & 0 &  \cdots   & 1  \\
 \end {array}
 } \right )
]]></fr:tex>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
  </fr:mainmatter>
  <fr:backmatter>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="References">References</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Context">Context</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Backlinks">Backlinks</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Related">Related</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-all-exercises/</fr:uri>
            <fr:display-uri>focs-all-exercises</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-all-exercises/</fr:route>
            <fr:title text="All exercises">All exercises</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Every exercise in the course, collected automatically from the lecture notes.</html:p>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-4/</fr:uri>
                <fr:display-uri>focs-ex-8-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-4/</fr:route>
                <fr:title text="Exercises › A map for options"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › A map for options</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>The type <html:code>'a option</html:code>, declared below, can be viewed as a type of lists having at most one element.
(It is typically used as an alternative to <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">exceptions</fr:link>.) Declare an analogue of the function <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>
for type <html:code>'a option</html:code>.</html:p>
                <html:pre><![CDATA[type 'a option = None | Some of 'a]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-1/</fr:uri>
                <fr:display-uri>focs-ex-9-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-1/</fr:route>
                <fr:title text="Exercises › A map for sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › A map for sequences</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an analogue of <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> for sequences.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-3/</fr:uri>
                <fr:display-uri>focs-ex-4-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-3/</fr:route>
                <fr:title text="Exercises › A non-exhaustive zip"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › A non-exhaustive zip</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>How does this version of <html:code>zip</html:code> differ from <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local">the one above</fr:link>?</html:p>
                <html:pre><![CDATA[let rec zip xs ys =
  match xs, ys with
  | (x::xs, y::ys) -> (x, y) :: zip xs ys
  | ([], [])   -> []]]></html:pre>
                <html:pre><![CDATA[Lines 2-4, characters 5-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(_::_, [])]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-4/</fr:uri>
                <fr:display-uri>focs-ex-2-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-4/</fr:route>
                <fr:title text="Exercises › A tighter recurrence bound"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › A tighter recurrence bound</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Find an upper bound for the recurrence given by <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+1]]></fr:tex>.  You should be
able to find a tighter bound than <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-4/</fr:uri>
                <fr:display-uri>focs-ex-6-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-4/</fr:route>
                <fr:title text="Exercises › A type for arithmetic expressions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › A type for arithmetic expressions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Give the declaration of an OCaml type for arithmetic expressions that have the following
possibilities: floating-point numbers, variables (represented by strings), or expressions of the form <fr:tex display="inline"><![CDATA[-E]]></fr:tex>,
<fr:tex display="inline"><![CDATA[E+E]]></fr:tex>, <fr:tex display="inline"><![CDATA[E\times  E]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-5/</fr:uri>
                <fr:display-uri>focs-ex-9-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-5/</fr:route>
                <fr:title text="Exercises › All lists of zeroes and ones"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › All lists of zeroes and ones</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code the lazy list whose elements are all ordinary lists of zeroes and ones, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 1]; [1; 0]; [1; 1]; [0; 0; 0]; </html:code>….  (Taken from the exam question
2003 Paper 1 Question 5.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-5/</fr:uri>
                <fr:display-uri>focs-ex-10-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-5/</fr:route>
                <fr:title text="Exercises › An implicit infinite tree"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › An implicit infinite tree</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the following OCaml function.</html:p>
                <html:pre><![CDATA[let next n = [2 * n; 2 * n + 1]]]></html:pre>
                <html:p>If we regard it as representing a tree, where the subtrees are computed from the current label, what
tree does <html:code>next 1</html:code> represent?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-2/</fr:uri>
                <fr:display-uri>focs-ex-10-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-2/</fr:route>
                <fr:title text="Exercises › Array-based circular queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Array-based circular queues</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>The traditional way to implement queues uses a fixed-length array. Two indices into the array
indicate the start and end of the queue, which wraps around from the end of the array to the start.
How appropriate is such a data structure for implementing <fr:link href="/~avsm2/fcs/focs-bfs-dfs/" title="Breadth-First v Depth-First Tree Traversal" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/" display-uri="focs-bfs-dfs" type="local">breadth-first search</fr:link>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-4/</fr:uri>
                <fr:display-uri>focs-ex-4-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-4/</fr:route>
                <fr:title text="Exercises › Assumptions in making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Assumptions in making change</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What assumptions do the <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">‘making change’</fr:link> functions make about the variables <html:code>till</html:code> and <html:code>amt</html:code>?
Describe what could happen if these assumptions were violated.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-2/</fr:uri>
                <fr:display-uri>focs-ex-1-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-2/</fr:route>
                <fr:title text="Exercises › Comparing and adding years"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Comparing and adding years</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Using the date representation of <fr:link href="/~avsm2/fcs/focs-ex-1-1/" title="Exercises › Two-digit year windowing" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/" display-uri="focs-ex-1-1" type="local">the previous exercise</fr:link>, code OCaml functions to (a) compare two
years (b) add/subtract some given number of years from another year.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-3/</fr:uri>
                <fr:display-uri>focs-ex-5-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-3/</fr:route>
                <fr:title text="Exercises › Complexity of bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of bubble sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another sorting algorithm (bubble sort) consists of looking at adjacent pairs of elements,
exchanging them if they are out of order and repeating this process until no more exchanges are
possible. State, with justification, the time complexity of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-1/</fr:uri>
                <fr:display-uri>focs-ex-5-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-1/</fr:route>
                <fr:title text="Exercises › Complexity of selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of selection sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another sorting algorithm (selection sort) consists of looking at the elements to be sorted,
identifying and removing a minimal element, which is placed at the head of the result. The tail is
obtained by recursively sorting the remaining elements. State, with justification, the time
complexity of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-2/</fr:uri>
                <fr:display-uri>focs-ex-9-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-2/</fr:route>
                <fr:title text="Exercises › Concatenating infinite sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Concatenating infinite sequences</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the list function <html:code>concat</html:code>, which concatenates a list of lists to form a single list. Can
it be generalised to concatenate a sequence of sequences? What can go wrong?</html:p>
                <html:pre><![CDATA[let rec concat = function
| [] -> []
| l::ls -> l @ concat ls]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-5/</fr:uri>
                <fr:display-uri>focs-ex-4-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-5/</fr:route>
                <fr:title text="Exercises › Counting ways of making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Counting ways of making change</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the number of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">ways of making change</fr:link> for <fr:tex display="inline"><![CDATA[n]]></fr:tex> (ignoring order) is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> if there are two
legal coin values. What if there are three, four, … coin values?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-1/</fr:uri>
                <fr:display-uri>focs-ex-6-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-1/</fr:route>
                <fr:title text="Exercises › Days of the week type"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Days of the week type</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Give the declaration of an OCaml type for the days of the week. Comment on the practicality of such
a type in a calendar application.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-4/</fr:uri>
                <fr:display-uri>focs-ex-7-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-4/</fr:route>
                <fr:title text="Exercises › Deleting from a search tree"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Deleting from a search tree</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Describe an algorithm for deleting an entry from a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>. Comment on the suitability of
your approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-3/</fr:uri>
                <fr:display-uri>focs-ex-11-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-3/</fr:route>
                <fr:title text="Exercises › Effects in a while condition"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Effects in a while condition</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What is the effect of <fr:tex display="inline"><![CDATA[\tt  while \, C_1; \; B \, do \, C_2 \, done]]></fr:tex> ?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-6/</fr:uri>
                <fr:display-uri>focs-ex-9-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-6/</fr:route>
                <fr:title text="Exercises › Enumerating palindromes"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Enumerating palindromes</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>(Continuing the previous exercise.)
A <html:em>palindrome</html:em> is a list that equals its own reverse. Code the lazy list whose elements are all
palindromes of 0s and 1s, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 0; 0]; [0; 1; 0]; [1; 1]; [1; 0; 1]; [1; 1; 1]; [0; 0; 0; 0]; </html:code>, …. You
may take the reversal function <html:code>List.rev</html:code> as given.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-5/</fr:uri>
                <fr:display-uri>focs-ex-6-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-5/</fr:route>
                <fr:title text="Exercises › Evaluating expressions with exceptions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Evaluating expressions with exceptions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Continuing the previous exercise, write a function that evaluates an expression. If the expression
contains any variables, your function should raise an <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> indicating the variable name.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-3/</fr:uri>
                <fr:display-uri>focs-ex-3-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-3/</fr:route>
                <fr:title text="Exercises › Even-numbered elements"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Even-numbered elements</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to return the list consisting of the even-numbered elements of the list given as its
argument. For example, given <html:code>[a; b; c; d]</html:code> it should return <html:code>[b; d]</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-4/</fr:uri>
                <fr:display-uri>focs-ex-11-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-4/</fr:route>
                <fr:title text="Exercises › Exchanging two references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Exchanging two references</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a function to exchange the values of two <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link>, <html:code>xr</html:code> and <html:code>yr</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-2/</fr:uri>
                <fr:display-uri>focs-ex-2-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-2/</fr:route>
                <fr:title text="Exercises › Extending the complexity table"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Extending the complexity table</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Add a column to the <fr:link href="/~avsm2/fcs/focs-sillysum/" title="Silly Summing the First n Integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/" display-uri="focs-sillysum" type="local">table of complexities</fr:link> from <html:em>The Design and Analysis of Computer Algorithms</html:em> with the heading <html:em>60 hours:</html:em></html:p>
                <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>60 hours</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td /></html:tr>
</html:table>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-5/</fr:uri>
                <fr:display-uri>focs-ex-1-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-5/</fr:route>
                <fr:title text="Exercises › Floating-point error by repeated addition"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Floating-point error by repeated addition</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Because computer arithmetic is based on binary numbers, simple decimals such as 0.1 often cannot be
represented exactly. Write a function <html:code>mul</html:code> that performs the computation</html:p>
                <fr:tex display="block"><![CDATA[\underbrace {x+x+\cdots +x}_{n}]]></fr:tex>
                <html:p>where <fr:tex display="inline"><![CDATA[x]]></fr:tex> has type <html:code>float</html:code>. (It is essential to use repeated addition rather than multiplication!)</html:p>
                <html:p>The value computed with <html:code>n = 10000</html:code> and <html:code>x = 0.1</html:code> may print as
<html:code>1000.0</html:code>, which looks exact. If that happens, then evaluate the
expression <html:code>mul 0.1 10000 -. 1000.0</html:code></html:p>
                <html:p>An error of this type has been blamed for the failure of an American Patriot Missile battery to
intercept an incoming Iraqi missile during the <fr:link href="https://en.wikipedia.org/wiki/MIM-104_PatriotFailure_at_Dhahran" type="external">first Gulf War</fr:link>.
The missile hit an American Army barracks, killing 28.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-6/</fr:uri>
                <fr:display-uri>focs-ex-1-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-6/</fr:route>
                <fr:title text="Exercises › Golden ratio instability"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Golden ratio instability</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Another example of the <fr:link href="/~avsm2/fcs/focs-floating-point/" title="Example 2: Floating Point Numbers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/" display-uri="focs-floating-point" type="local">inaccuracy of floating-point arithmetic</fr:link> takes the golden ratio
<fr:tex display="inline"><![CDATA[\phi \approx 1.618\ldots ]]></fr:tex> as its starting point:</html:p>
                <fr:tex display="block"><![CDATA[\gamma _0 = \frac {1+\sqrt 5}{2} \quad \text {and}\quad \gamma _{n+1} = \frac {1}{\gamma _n-1}.]]></fr:tex>
                <html:p>In theory, it is easy to prove that <fr:tex display="inline"><![CDATA[\gamma _n=\cdots  = \gamma _1 = \gamma _0]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>. Code this
computation in OCaml and report the value of <fr:tex display="inline"><![CDATA[\gamma _{50}]]></fr:tex>. <html:em>Hint:</html:em> in OCaml, <fr:tex display="inline"><![CDATA[\sqrt 5]]></fr:tex> is expressed
as <html:code>sqrt 5.0</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-4/</fr:uri>
                <fr:display-uri>focs-ex-5-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-4/</fr:route>
                <fr:title text="Exercises › Implementing bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing bubble sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Implement bubble sort (see previous exercise) using OCaml.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-5/</fr:uri>
                <fr:display-uri>focs-ex-7-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-5/</fr:route>
                <fr:title text="Exercises › Implementing deletion"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Implementing deletion</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code the delete function outlined in the previous exercise.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-2/</fr:uri>
                <fr:display-uri>focs-ex-5-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-5-2/</fr:route>
                <fr:title text="Exercises › Implementing selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing selection sort</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Implement selection sort (see previous exercise) using OCaml.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-1/</fr:uri>
                <fr:display-uri>focs-ex-7-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-1/</fr:route>
                <fr:title text="Exercises › Insertion order in search trees"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion order in search trees</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Draw the <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link> that arises from successively inserting the following pairs into the
empty tree: <html:code>("Alice", 6)</html:code>, <html:code>("Tobias", 2)</html:code>, <html:code>("Gerald", 8)</html:code>, <html:code>("Lucy", 9)</html:code>. Then repeat this
task using the order <html:code>("Gerald", 8)</html:code>, <html:code>("Alice", 6)</html:code>, <html:code>("Lucy", 9)</html:code>, <html:code>("Tobias", 2)</html:code>. Why are
results different?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-2/</fr:uri>
                <fr:display-uri>focs-ex-7-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-2/</fr:route>
                <fr:title text="Exercises › Insertion with collision detection"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion with collision detection</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an insertion function for <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link>. It should resemble the existing <fr:link href="/~avsm2/fcs/focs-bst-update/" title="Update" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/" display-uri="focs-bst-update" type="local"><html:code>update</html:code></fr:link>
function except that it should raise the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Collision</html:code> if the item to be inserted is already
present.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-1/</fr:uri>
                <fr:display-uri>focs-ex-2-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-1/</fr:route>
                <fr:title text="Exercises › Iterative power"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Iterative power</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version of the function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-2/</fr:uri>
                <fr:display-uri>focs-ex-11-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-2/</fr:route>
                <fr:title text="Exercises › Iterative power with while"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Iterative power with while</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a version of function <html:code>power</html:code> (<fr:link href="/~avsm2/fcs/focs-intro/" title="Introduction to Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" type="local">Lecture <fr:contextual-number uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" /></fr:link>) using <html:code>while</html:code> instead of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-2/</fr:uri>
                <fr:display-uri>focs-ex-3-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-2/</fr:route>
                <fr:title text="Exercises › Last element of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Last element of a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to return the last element of a non-empty list. How efficiently can this be done?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-4/</fr:uri>
                <fr:display-uri>focs-ex-9-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-4/</fr:route>
                <fr:title text="Exercises › Lazy binary trees"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Lazy binary trees</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A <html:em>lazy binary tree</html:em> is either empty or is a branch containing a label and two lazy <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>,
possibly to infinite depth. Present an OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> to represent lazy binary trees, along with a
function that accepts a lazy binary tree and produces a lazy list that contains all of the tree’s
labels. (Taken from the exam question 2008 Paper 1 Question 5.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-2/</fr:uri>
                <fr:display-uri>focs-ex-8-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-2/</fr:route>
                <fr:title text="Exercises › Lexicographic orderings"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Lexicographic orderings</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>There are many ways of combining orderings. The <html:code>lexicographic ordering</html:code> uses two keys for
comparisons. It is specified by</html:p>
                <fr:tex display="block"><![CDATA[(x',y')<(x,y)\iff  x'<x \vee  (x'=x \wedge  y'<y).]]></fr:tex>
                <html:p>Write an OCaml function to lexicographically combine two orderings, supplied as functions. Explain
how it allows function <fr:link href="/~avsm2/fcs/focs-partial-application/" title="Partial Application: A Curried Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/" display-uri="focs-partial-application" type="local"><html:code>insort</html:code></fr:link> to sort a list of pairs.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-7/</fr:uri>
                <fr:display-uri>focs-ex-7-7</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-7/</fr:route>
                <fr:title text="Exercises › Linear traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Linear traversals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>preord</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>inord</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>postord</html:code></fr:link> all take linear time in the size of the
tree.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-1/</fr:uri>
                <fr:display-uri>focs-ex-11-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-1/</fr:route>
                <fr:title text="Exercises › Lists of references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Lists of references</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Comment, with examples, on the differences between an <html:code>int ref list</html:code> and an <html:code>int list ref</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-3/</fr:uri>
                <fr:display-uri>focs-ex-9-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-9-3/</fr:route>
                <fr:title text="Exercises › Making change lazily"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Making change lazily</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function to <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">make change</fr:link> using <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, delivering the sequence of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">all possible ways of
making change</fr:link>. Using sequences allows us to compute solutions one at a time when there exists an
astronomical number. Represent lists of coins using ordinary lists. (<html:em>Hint</html:em>: to  benefit from
laziness you may need to pass around the sequence of alternative solutions as a function of type
<html:code>unit -&gt; (int list) seq</html:code>.)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-5/</fr:uri>
                <fr:display-uri>focs-ex-8-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-5/</fr:route>
                <fr:title text="Exercises › Making change with map"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Making change with map</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Recall the making change function of <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">More on Lists</fr:link>:</html:p>
                <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                <html:p>Function <html:code>allc</html:code> applies the function ‘cons a <html:code>c</html:code>’ to every element of a list. Eliminate it by
declaring a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried</fr:link> cons function and applying <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-3/</fr:uri>
                <fr:display-uri>focs-ex-8-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-3/</fr:route>
                <fr:title text="Exercises › Mapping over lists of lists"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Mapping over lists of lists</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Without using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> write a function <html:code>map2</html:code> such that <html:code>map2 f</html:code> is equivalent to <html:code>map (map f)</html:code>. The
obvious solution requires declaring two recursive functions. Try to get away with only one by
exploiting nested <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-5/</fr:uri>
                <fr:display-uri>focs-ex-11-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-11-5/</fr:route>
                <fr:title text="Exercises › Matrix operations on arrays"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Matrix operations on arrays</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Arrays of multiple dimensions are represented in OCaml by arrays of arrays. Write functions to
(a) create an <fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> identity matrix, given <fr:tex display="inline"><![CDATA[n]]></fr:tex>, and
(b) to <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local">transpose</fr:link> an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix. Identity matrices have the following form:</html:p>
                <fr:tex display="block"><![CDATA[
\left ( {
\begin {array}{cccc}
   1 & 0 &  \cdots   & 0  \\
   0 & 1 &  \cdots   & 0  \\
    \vdots   &  \vdots   &  \ddots   &  \vdots    \\
   0 & 0 &  \cdots   & 1  \\
 \end {array}
 } \right )
]]></fr:tex>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-2/</fr:uri>
                <fr:display-uri>focs-ex-4-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-2/</fr:route>
                <fr:title text="Exercises › Partitioning integers by sign"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Partitioning integers by sign</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function that takes a list of integers and returns two lists, the first consisting of all
non-negative numbers found in the input and the second consisting of all the negative numbers.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-4/</fr:uri>
                <fr:display-uri>focs-ex-3-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-4/</fr:route>
                <fr:title text="Exercises › Polymorphic types of id and loop"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Polymorphic types of id and loop</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Consider the <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic types</fr:link> in these two function declarations:</html:p>
                <html:pre><![CDATA[# let id x = x
val id : 'a -> 'a = <fun>
# let rec loop x = loop x
val loop : 'a -> 'b = <fun>]]></html:pre>
                <html:p>Explain why these types make logical sense, preventing run time type errors, even for expressions
like <html:code>id [id [id 0]]</html:code> or <html:code>loop true / loop 3</html:code>. (<html:code>/</html:code> is the integer division operator in OCaml)</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-6/</fr:uri>
                <fr:display-uri>focs-ex-7-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-6/</fr:route>
                <fr:title text="Exercises › Quadratic traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Quadratic traversals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>preorder</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>postorder</html:code></fr:link> all require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time in the worst
case, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the size of the tree.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-6/</fr:uri>
                <fr:display-uri>focs-ex-4-6</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-6/</fr:route>
                <fr:title text="Exercises › Reasoning from polymorphic types"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Reasoning from polymorphic types</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>We know nothing about the functions <html:code>f</html:code> and <html:code>g</html:code> other than their polymorphic types:
<html:code>val f : 'a * 'b -&gt; 'b * 'a</html:code> and <html:code>val g : 'a -&gt; 'a list</html:code>.
Suppose that <html:code>f (1, true)</html:code> and <html:code>g 0</html:code> are evaluated and return their results. State, with reasons,
what you think the resulting values will be.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-3/</fr:uri>
                <fr:display-uri>focs-ex-1-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-3/</fr:route>
                <fr:title text="Exercises › Redundant conditionals"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Redundant conditionals</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Why would no experienced programmer write an expression of the form <html:code>if</html:code> … <html:code>then true else false</html:code>?
What about expressions of the form <html:code>if</html:code> … <html:code>then false else true</html:code>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-3/</fr:uri>
                <fr:display-uri>focs-ex-7-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-3/</fr:route>
                <fr:title text="Exercises › Returning the old value on collision"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Returning the old value on collision</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Continuing the previous exercise, it would be natural for exceptional <html:code>Collision</html:code> to return the
value previously stored in the dictionary. Why is that goal difficult to achieve?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-3/</fr:uri>
                <fr:display-uri>focs-ex-10-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-3/</fr:route>
                <fr:title text="Exercises › Rewriting breadth with let"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Rewriting breadth with let</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a version of the function <fr:link href="/~avsm2/fcs/focs-bfs-queues/" title="Breadth-First Tree Traversal — Using Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/" display-uri="focs-bfs-queues" type="local"><html:code>breadth</html:code></fr:link> using a nested <html:code>let</html:code> construction rather than
<html:code>match</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-4/</fr:uri>
                <fr:display-uri>focs-ex-10-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-4/</fr:route>
                <fr:title text="Exercises › Search with a branching factor near one"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Search with a branching factor near one</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p><fr:link href="/~avsm2/fcs/focs-iterative-deepening/" title="Iterative deepening: Another Exhaustive Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/" display-uri="focs-iterative-deepening" type="local">Iterative deepening</fr:link> is inappropriate if <fr:tex display="inline"><![CDATA[b\approx 1]]></fr:tex>, where <fr:tex display="inline"><![CDATA[b]]></fr:tex> is the branching factor. What search
strategy is appropriate in this case?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-1/</fr:uri>
                <fr:display-uri>focs-ex-4-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-4-1/</fr:route>
                <fr:title text="Exercises › Set union without repetitions"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Set union without repetitions</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Sets can be represented in OCaml using lists containing no duplicated items
(i.e. where no item is equal to another using <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link> comparison).</html:p>
                <html:p>Using the <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link> function defined above, code a function to implement set
union. It should avoid introducing repetitions, for example the union of the
lists <html:code>[4; 7; 1]</html:code> and <html:code>[6; 4; 7]</html:code> should be <html:code>[1; 6; 4; 7]</html:code> (though the order
does not matter).</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-8/</fr:uri>
                <fr:display-uri>focs-ex-7-8</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-7-8/</fr:route>
                <fr:title text="Exercises › Shifting a functional array"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Shifting a functional array</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write a function to remove the first element from a <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional array</fr:link>. All the other elements are to
have their subscripts reduced by one. The cost of this operation should be linear in the size of the
array.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-3/</fr:uri>
                <fr:display-uri>focs-ex-2-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-2-3/</fr:route>
                <fr:title text="Exercises › Simplifying sums in O notation"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Simplifying sums in O notation</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Let <fr:tex display="inline"><![CDATA[g_1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[g_k]]></fr:tex> be functions such that <fr:tex display="inline"><![CDATA[g_i(n)\ge 0]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[k]]></fr:tex> and all sufficiently
large <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                <html:p>Show that if <fr:tex display="inline"><![CDATA[f(n) = O(a_1 g_1(n)+\cdots +a_k g_k(n))]]></fr:tex> then <fr:tex display="inline"><![CDATA[f(n) = O(g_1(n)+\cdots +g_k(n))]]></fr:tex>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-1/</fr:uri>
                <fr:display-uri>focs-ex-3-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-1/</fr:route>
                <fr:title text="Exercises › Summing a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Summing a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function</fr:link> to compute the sum of a list’s elements. Then code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version
and comment on the improvement in efficiency.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-2/</fr:uri>
                <fr:display-uri>focs-ex-6-2</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-2/</fr:route>
                <fr:title text="Exercises › Summing tree labels"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Summing tree labels</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Write an OCaml function taking a binary tree labelled with integers and returning their sum.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-5/</fr:uri>
                <fr:display-uri>focs-ex-3-5</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-3-5/</fr:route>
                <fr:title text="Exercises › Tails of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Tails of a list</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Code a function <html:code>tails</html:code> to return the list of the tails of its argument. For example, given
<html:code>[1; 2; 3]</html:code> it should return <html:code>[[1; 2; 3]; [2; 3]; [3]; []]</html:code>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-1/</fr:uri>
                <fr:display-uri>focs-ex-8-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-8-1/</fr:route>
                <fr:title text="Exercises › The argument-swapping functional"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › The argument-swapping functional</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>What does the following function do, and what are its uses?</html:p>
                <html:pre><![CDATA[let sw f x y = f y x]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-1/</fr:uri>
                <fr:display-uri>focs-ex-10-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-10-1/</fr:route>
                <fr:title text="Exercises › Tree-based queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Tree-based queues</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Suppose that we have an implementation of queues, based on <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>, such that each operation
takes logarithmic time in the worst case. Outline the advantages and drawbacks of such an
implementation compared with one presented above.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/</fr:uri>
                <fr:display-uri>focs-ex-1-1</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-1/</fr:route>
                <fr:title text="Exercises › Two-digit year windowing"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Two-digit year windowing</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>One solution to the <fr:link href="/~avsm2/fcs/focs-dates/" title="Example 1: Dates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/" display-uri="focs-dates" type="local">year 2000 bug</fr:link> involves storing years as two digits, but interpreting them such
that 50 means 1950 and 49 means 2049. Comment on the merits and demerits of this approach.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-4/</fr:uri>
                <fr:display-uri>focs-ex-1-4</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-1-4/</fr:route>
                <fr:title text="Exercises › Type inference in power"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Type inference in power</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Functions <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> both return a <html:code>float</html:code>. The definition of <html:code>npower</html:code> returns the float
value <html:code>1.0</html:code> in its base case. The definition of <html:code>power</html:code> does not, so how does the OCaml type checker
know that <html:code>power</html:code> returns a <html:code>float</html:code>?</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-3/</fr:uri>
                <fr:display-uri>focs-ex-6-3</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-ex-6-3/</fr:route>
                <fr:title text="Exercises › What ftree builds"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › What ftree builds</fr:title>
                <fr:taxon>Exercise</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Using the <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">definition of <html:code>'a tree</html:code></fr:link> from before:</html:p>
                <html:pre><![CDATA[type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                <html:p>Examine the following function declaration. What does <html:code>ftree (1, n)</html:code> accomplish?</html:p>
                <html:pre><![CDATA[let rec ftree k n =
  if n = 0 then Lf
  else Br (k, ftree (2 * k) (n - 1), ftree (2 * k + 1) (n - 1))]]></html:pre>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/</fr:uri>
            <fr:display-uri>anil-madhavapeddy</fr:display-uri>
            <fr:route>/~avsm2/fcs/anil-madhavapeddy/</fr:route>
            <fr:title text="Anil Madhavapeddy">Anil Madhavapeddy</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p><fr:link href="https://anil.recoil.org/" type="external">Anil Madhavapeddy</fr:link> lectures the Foundations of Computer Science course at the University of Cambridge.</html:p>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/</fr:uri>
            <fr:display-uri>focs-glossary</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-glossary/</fr:route>
            <fr:title text="Glossary">Glossary</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Definitions of the course’s core concepts, collected automatically.</html:p>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstract-data-type/</fr:uri>
                <fr:display-uri>focs-def-abstract-data-type</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-abstract-data-type/</fr:route>
                <fr:title text="Abstract data type">Abstract data type</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent them. Before choosing the
internal representation for a data structure, you need to specify the full set of
operations. Abstract types can be declared in any modern programming language:
Java’s <html:em>objects</html:em> serve this role, as do OCaml’s modules.
Introduced in <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">Dictionaries</fr:link>, and applied to
<fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local">queues</fr:link> and <fr:link href="/~avsm2/fcs/focs-stacks/" title="Another Abstract Data Type: Stacks" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/" display-uri="focs-stacks" type="local">stacks</fr:link> later on.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/</fr:uri>
                <fr:display-uri>focs-def-abstraction-barrier</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-abstraction-barrier/</fr:route>
                <fr:title text="Abstraction barrier">Abstraction barrier</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Large systems can only be understood in levels: the interface to the higher
level should supply the advertised services and, just as important, block access
to the means by which those services are implemented. This abstraction barrier
allows one level to be changed without affecting levels above.
Introduced in <fr:link href="/~avsm2/fcs/focs-basic-concepts/" title="Basic Concepts in Computer Science" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-basic-concepts/" display-uri="focs-basic-concepts" type="local">Basic Concepts in Computer Science</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/</fr:uri>
                <fr:display-uri>focs-def-algebraic-datatype</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-algebraic-datatype/</fr:route>
                <fr:title text="Algebraic datatype">Algebraic datatype</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>OCaml generalises the notion of enumeration type to allow data to be
associated with each constructor: some constructors are values all by themselves,
while others create values from arguments. Constructors with arguments are
<html:em>distinct values</html:em>, and values built from different constructors of one
datatype can belong to a single list.
Introduced in <fr:link href="/~avsm2/fcs/focs-constructors-args/" title="A Datatype whose Constructors have Arguments" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/" display-uri="focs-constructors-args" type="local">A Datatype whose Constructors have Arguments</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/</fr:uri>
                <fr:display-uri>focs-def-binary-search-tree</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-binary-search-tree/</fr:route>
                <fr:title text="Binary search tree">Binary search tree</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A binary search tree works for keys that have a total ordering, such as
strings. Each branch of the tree carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree
holds smaller keys and its right subtree holds greater keys. If the tree remains
reasonably balanced, then update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of
size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary Search Trees</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/</fr:uri>
                <fr:display-uri>focs-def-currying</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-currying/</fr:route>
                <fr:title text="Currying">Currying</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Currying is the technique of expressing a function taking multiple arguments
as nested functions, each taking a single argument. A <html:em>curried function</html:em>
returns another function as its result, so the arguments are supplied one after
another.
Introduced in <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Curried Functions</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/</fr:uri>
                <fr:display-uri>focs-def-exception</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-exception/</fr:route>
                <fr:title text="Exception">Exception</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>An exception signals that something has gone <html:em>wrong</html:em> during a computation,
such as division by zero or pattern matching failure. Raising an exception
abandons the current computation; handling the exception attempts an alternative
computation. The raising and the handling can be far apart in the code, and
errors of <html:em>different sorts</html:em> can be handled separately.
Introduced in <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">Error Handling: Exceptions</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/</fr:uri>
                <fr:display-uri>focs-def-higher-order-function</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-higher-order-function/</fr:route>
                <fr:title text="Higher-order function">Higher-order function</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>In mathematics, a <html:em>functional</html:em> or <html:em>higher-order function</html:em> is a function
that operates on other functions. In OCaml, functions can be passed as arguments
to other functions, returned as results, and put into lists, trees and so on—but
<html:em>not</html:em> tested for equality.
Introduced in <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">Functions as Values</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/</fr:uri>
                <fr:display-uri>focs-def-lazy-list</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-lazy-list/</fr:route>
                <fr:title text="Lazy list">Lazy list</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A lazy list is a list of possibly <html:em>infinite</html:em> length whose elements are
<html:em>computed upon demand</html:em>; in OCaml we implement laziness by <html:em>delaying
evaluation</html:em> of the tail of the list. The traditional word “stream” is reserved in
OCaml parlance for input/output channels, so we call lazy lists <html:em>sequences</html:em>
instead.
Introduced in <fr:link href="/~avsm2/fcs/focs-lazy-lists/" title="Lazy Lists (or Streams)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/" display-uri="focs-lazy-lists" type="local">Lazy Lists</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/</fr:uri>
                <fr:display-uri>focs-def-mutable-reference</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-mutable-reference/</fr:route>
                <fr:title text="Mutable reference">Mutable reference</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A reference is a cell in the store, also called a “location”: <html:code>ref E</html:code>
creates a reference with initial contents the value of <html:code>E</html:code>, <html:code>!P</html:code>
returns the current contents of reference <html:code>P</html:code> (an operation called
<html:em>dereferencing</html:em>), and <html:code>P := E</html:code> updates the contents of <html:code>P</html:code> to the
value of <html:code>E</html:code>. If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the
type of references to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">OCaml Primitives for References</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/</fr:uri>
                <fr:display-uri>focs-def-o-notation</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-o-notation/</fr:route>
                <fr:title text="O notation">O notation</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Formally, <fr:tex display="inline"><![CDATA[f(n) = O(g(n))]]></fr:tex> provided <fr:tex display="inline"><![CDATA[|f(n)| \leq  c|g(n)|]]></fr:tex> as <fr:tex display="inline"><![CDATA[n\to \infty ]]></fr:tex>,
that is, for some constant <fr:tex display="inline"><![CDATA[c]]></fr:tex> and all <html:em>sufficiently large</html:em> <fr:tex display="inline"><![CDATA[n]]></fr:tex>. The “Big
O” notation is commonly used to describe efficiency—to be precise,
<html:em>asymptotic complexity</html:em>—by looking only at the most significant term and
ignoring constant factors.
Introduced in <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local">Comparing Algorithms: O Notation</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/</fr:uri>
                <fr:display-uri>focs-def-pattern-matching</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-pattern-matching/</fr:route>
                <fr:title text="Pattern matching">Pattern matching</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>Pattern matching takes a value apart by matching it against the forms that
value can have, letting <html:em>one</html:em> function declaration handle several cases,
separated by a vertical bar <html:code>|</html:code>. Taking a list apart using combinations of
<html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right; fortunately, it is seldom necessary
because of pattern-matching.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/</fr:uri>
                <fr:display-uri>focs-def-polymorphism</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-polymorphism/</fr:route>
                <fr:title text="Polymorphism">Polymorphism</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A polymorphic function allows flexibility in the types of its arguments and
results: the list primitives <html:code>null</html:code>, <html:code>hd</html:code> and <html:code>tl</html:code> work whatever
the element type is. Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type
variables</html:em> and stand for any types, and code written using them is still checked
for type correctness at compile time.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/</fr:uri>
                <fr:display-uri>focs-def-recursion</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-recursion/</fr:route>
                <fr:title text="Recursion">Recursion</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A function is recursive if it calls itself. You can spot a recursive function
by the <html:code>rec</html:code> keyword in its definition: this indicates that any invocation
of the function name within the function body should call itself. The recursion
is meaningful because it terminates: we reduce the problem to smaller problems,
and this cannot go on forever.
Introduced in <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local">Raising a Number to a Power</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/</fr:uri>
                <fr:display-uri>focs-def-tail-recursion</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-def-tail-recursion/</fr:route>
                <fr:title text="Tail recursion">Tail recursion</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>A recursive function whose computation does not nest is called <html:em>iterative</html:em>
or <html:em>tail-recursive</html:em>: the recursive calls do not nest, so the work is done
immediately rather than on the way back out. Many functions can be made
iterative by introducing an extra argument, which is often called an
<html:em>accumulator</html:em>.
Introduced in <fr:link href="/~avsm2/fcs/focs-summing-iter/" title="Iteratively summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/" display-uri="focs-summing-iter" type="local">Iteratively summing the first n integers</fr:link>.</html:p>
                <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>
                <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
              </fr:author>
            </fr:authors>
            <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topics/</fr:uri>
            <fr:display-uri>focs-topics</fr:display-uri>
            <fr:route>/~avsm2/fcs/focs-topics/</fr:route>
            <fr:title text="Topic index">Topic index</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>Sections and exercises grouped by topic, collected automatically from tags on each tree.</html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-recursion/</fr:uri>
                <fr:display-uri>focs-topic-recursion</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-recursion/</fr:route>
                <fr:title text="Recursion">Recursion</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/</fr:uri>
                    <fr:display-uri>focs-change-all</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-all/</fr:route>
                    <fr:title text="All Ways of Making Change">All Ways of Making Change</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Now we generalise the problem to return the list of <html:em>all possible ways</html:em> of making change,
and write a new <html:code>change</html:code> function.</html:p>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                    <html:p>Look at the type: the result is now a list of lists.
The code will also never raise <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>.  It expresses failure by returning an
empty list of solutions: it returns <html:code>[]</html:code> if the till is empty and the
amount is nonzero.</html:p>
                    <html:p>If the amount is zero, then there is only one way of making change;
the result should be <html:code><![CDATA[[[]]]]></html:code>.  This is success in the base case.</html:p>
                    <html:p>In nontrivial cases, there are two sources of solutions: to use a coin (if
possible) and decrease the amount accordingly, or to remove the current coin
value from consideration.</html:p>
                    <html:p>The function <html:code>allc</html:code> is declared locally in order to make use
of <html:code>c</html:code>, the current coin.  It adds an extra <html:code>c</html:code> to all the
solutions returned by the recursive call to make change for <html:code>amt - c</html:code>.</html:p>
                    <html:p>Observe the naming convention: <html:code>cs</html:code> is a list of coins, while
<html:code>css</html:code> is a list of such lists.  The trailing ‘s’ is suggestive of a
plural.</html:p>
                    <html:p>This complicated program, and the even trickier one on the next slide, are
included as challenges.  Are you enthusiastic enough to work them out?  We
shall revisit the “making change” task later to illustrate <fr:link href="/~avsm2/fcs/focs-change-exceptions/" title="Making Change with Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/" display-uri="focs-change-exceptions" type="local">exception-handling</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-faster/</fr:uri>
                    <fr:display-uri>focs-change-faster</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-faster/</fr:route>
                    <fr:title text="All Ways of Making Change — Faster!">All Ways of Making Change — Faster!</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec change till amt chg chgs =
    match till, amt with
    | _       , 0   -> chg::chgs
    | []      , _   -> chgs
    | c::till , amt -> if amt < 0 then chgs
                       else change (c::till) (amt - c) (c::chg)
                                   (change till amt chg chgs)
val change : int list -> int -> int list -> int list list -> int list list =
  <fun>]]></html:pre>
                    <html:p>We’ve added <html:em>another</html:em> accumulating parameter!  Repeatedly improving simple code
is called <html:em>stepwise refinement</html:em>.</html:p>
                    <html:p>Two extra arguments eliminate many <html:code>::</html:code> and append operations from the previous
slide’s <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local"><html:code>change</html:code></fr:link> function.  The first, <html:code>chg</html:code>, accumulates the coins chosen so
far; one evaluation of <html:code>c::chg</html:code> replaces many evaluations of <html:code>allc</html:code>.  The
second, <html:code>chgs</html:code>, accumulates the list of solutions so far; it avoids the need
for <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link>.  This version runs several times faster than the previous one.</html:p>
                    <html:p>Making change is still extremely slow for an obvious reason: the number of
solutions grows rapidly in the amount being changed.  Using 50, 20, 10, 5,
2 and 1, there are 4366 ways of expressing 99.</html:p>
                    <html:p>Our three change functions illustrate a basic technique: program development
by stepwise refinement.  Begin by writing a very simple program and add
requirements individually.  Add efficiency refinements last of all.
Even if the simpler program cannot be included in the next version and has
to be discarded, one has learned about the task by writing it.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/</fr:uri>
                    <fr:display-uri>focs-making-change</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-making-change/</fr:route>
                    <fr:title text="An Application: Making Change">An Application: Making Change</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider a till that has unlimited supplies of coins.  The largest coins should be tried
first, to avoid giving change all in pennies.  The list of legal coin values,
called <html:code>till</html:code>, is given in descending order, such as 50, 20, 10, 5,
2 and 1.  (Recall that the <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">head of a list</fr:link> is the element most easily reached.)
The code for <html:code>change</html:code> is based on simple observations:</html:p>
                    <html:ul><html:li>Change for zero consists of no coins at all.  (Note the pattern of <html:code>0</html:code> in the first clause.)</html:li>
  <html:li>For a nonzero amount, try the largest available coin.  If it is small enough, use it and decrease the amount accordingly.</html:li>
  <html:li>Exclude from consideration any coins that are too large.</html:li></html:ul>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise (Failure "no more coins!")
    | c::till, amt -> if amt < c then change till amt
                      else c :: change (c::till) (amt - c)
val change : int list -> int -> int list = <fun>]]></html:pre>
                    <html:p>Although nobody considers making change for zero, this is the simplest way to
make the algorithm terminate.  Most iterative procedures become simplest if,
in their base case, they do nothing.  A base case of one instead of zero is
often a sign of a novice programmer.</html:p>
                    <html:ul><html:li>The <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> <html:em>terminates</html:em> when <html:code>amt = 0</html:code>.</html:li>
  <html:li>Tries the <html:em>largest coin first</html:em> to use large coins.</html:li>
  <html:li>The algorithm is <html:em>greedy</html:em> and can fail!</html:li></html:ul>
                    <html:p>The function can terminate either with success or failure.  It fails by
raising exception <html:code>Failure</html:code> namely if <html:code>till</html:code> becomes empty while <html:code>amt</html:code> is still nonzero.
(<fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">Exceptions</fr:link> will be discussed later.)</html:p>
                    <html:p>Unfortunately, failure can occur even when change can be made.  The greedy
"largest coin first" approach is to blame.  Suppose we have coins of values 5
and 2, and must make change for 6; the only way is <fr:tex display="inline"><![CDATA[6=2+2+2]]></fr:tex>, ignoring the 5.
<html:em>Greedy algorithms</html:em> are often effective, but not here.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-append-free/</fr:uri>
                    <fr:display-uri>focs-quicksort-append-free</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort-append-free/</fr:route>
                    <fr:title text="Append-Free Quicksort">Append-Free Quicksort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quik = function
    | ([], sorted) -> sorted
    | ([x], sorted) -> x::sorted
    | a::bs, sorted ->
       let rec part = function
         | l, r, [] -> quik (l, a :: quik (r, sorted))
         | l, r, x::xs ->
             if x <= a then
               part (x::l, r, xs)
             else
               part (l, x::r, xs)
       in
       part ([], [], bs)
val quik : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>The list <html:code>sorted</html:code> accumulates the result in the <html:em>combine</html:em> stage of
the quicksort algorithm.  We have again used the standard technique for
<fr:link href="/~avsm2/fcs/focs-rev/" title="Reversing a List in O(n)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/" display-uri="focs-rev" type="local">eliminating append</fr:link>.  Calling <html:code>quik(xs, sorted)</html:code> reverses the elements of
<html:code>xs</html:code> and prepends them to the list <html:code>sorted</html:code>.</html:p>
                    <html:p>Looking closely at <html:code>part</html:code>, observe that <html:code>quik(r, sorted)</html:code> is
performed first.  Then <html:code>a</html:code> is consed to this sorted list.  Finally,
<html:code>quik</html:code> is called again to sort the elements of <html:code>l</html:code>.</html:p>
                    <html:p>The speedup is significant.  An imperative quicksort coded in Pascal (taken
from <fr:link href="https://algs4.cs.princeton.edu/20sorting/" type="external">Sedgewick</fr:link>) is just slightly faster than function
<html:code>quik</html:code>.  The near-agreement is surprising because the computational overheads
of lists exceed those of arrays.  In realistic applications, comparisons are
the dominant cost and the overheads matter even less.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/</fr:uri>
                    <fr:display-uri>focs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-append/</fr:route>
                    <fr:title text="Append: List Concatenation">Append: List Concatenation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec append xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> x :: append xs ys
val append : 'a list -> 'a list -> 'a list = <fun>
# append [1; 2; 3] [4]
- : int list = [1; 2; 3; 4]
# let (@) = append
val ( @ ) : 'a list -> 'a list -> 'a list = <fun>
# [1; 2; 3] @ [4]
- : int list = [1; 2; 3; 4]]]></html:pre>
                    <html:p>Patterns can be as complicated as we like.  Here, the two patterns are
<html:code>[], ys</html:code> and <html:code>x::xs, ys</html:code>.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {append }[1; 2; 3] [4] \Rightarrow  &\; 1 :: \text {append }[2; 3]\;[4] \\
  \Rightarrow  &\; 1 :: (2 :: \text {append }[3]\;[4]) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: \text {append }[]\;[4])) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: [4])) \ [1; 2; 3; 4]
\end {aligned}
]]></fr:tex>
                    <html:p>Here is how append might be declared, also noting that we have defined <html:code>@</html:code> as
an infix operator that is a more convenient way to call <html:code>append</html:code> on two lists.
However, this function is also not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It scans its first
argument, sets up a string of <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code> operations</fr:link> (<html:code>::</html:code>) and finally does them.</html:p>
                    <html:p>It uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its first argument.
<html:em>Its costs are independent of its second argument.</html:em></html:p>
                    <html:p>An accumulating argument could make it iterative, but with considerable
complication.  The iterative version would still require <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time
because concatenation requires copying all the elements of the first list.
Therefore, we cannot hope for asymptotic gains; at best we can decrease the
constant factor involved in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>, but complicating the code is likely to
increase that factor.  Never add an accumulator merely out of habit.</html:p>
                    <html:p>Note append’s <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic type</fr:link>. It tells us that two lists can be joined if
their element types agree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/</fr:uri>
                    <fr:display-uri>focs-tree-traversal</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal/</fr:route>
                    <fr:title text="Aside: Traversing Trees (3 Methods)">Aside: Traversing Trees (3 Methods)</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec preorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      [v] @ preorder t1 @ preorder t2
val preorder : 'a tree -> 'a list = <fun>
# let rec inorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      inorder t1 @ [v] @ inorder t2
val inorder : 'a tree -> 'a list = <fun>
# let rec postorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      postorder t1 @ postorder t2 @ [v]
val postorder : 'a tree -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Tree traversal</html:em> means examining each node of a tree in some order.  <fr:link href="https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming" type="external">D. E.
Knuth</fr:link> has
identified three forms of tree traversal: preorder, inorder and
postorder.  We can code these “visiting orders” as functions
that convert trees into lists of labels.  Algorithms based on these notions
typically perform some action at each node; the functions above simply copy
the nodes into lists.  Consider the tree:</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmic3wbal56lpqlso6xcqsl6jfrutwygavrn3xds7c6ieywfjr7qdhm.svg" />
                    </html:figure>
                    <html:ul><html:li><html:code>preorder</html:code> visits the label first (“Polish notation”), yielding <html:code>ABDECFG</html:code></html:li>
<html:li><html:code>inorder</html:code> visits the label midway, yielding <html:code>DBEAFCG</html:code></html:li>
<html:li><html:code>postorder</html:code> visits the label last (“Reverse Polish”), yielding <html:code>DEBFGCA</html:code>. You might be familiar with this concept if you own an ancient RPN calculator!</html:li></html:ul>
                    <html:p>What is the use of <html:code>inorder</html:code>? Consider applying it to a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>: the
result is a sorted list of pairs. We could use this, for example, to merge two
binary search trees. It is not difficult to transform a sorted list of pairs
into a binary search tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-properties/</fr:uri>
                    <fr:display-uri>focs-tree-properties</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-properties/</fr:route>
                    <fr:title text="Basic Properties of Binary Trees">Basic Properties of Binary Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec count = function
  | Lf -> 0  (* number of branch nodes *)
  | Br (v, t1, t2) -> 1 + count t1 + count t2
val count : 'a tree -> int = <fun>
# let rec depth = function
  | Lf -> 0  (* length of longest path *)
  | Br (v, t1, t2) -> 1 + max (depth t1) (depth t2)
val depth : 'a tree -> int = <fun>]]></html:pre>
                    <html:p>The invariant <fr:tex display="inline"><![CDATA[\texttt {count}(t)\le  2^{\texttt {depth}(t)} - 1]]></fr:tex> holds in the functions above.</html:p>
                    <html:p>Functions on trees are expressed recursively using <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.  Both
functions above are analogous to <fr:link href="/~avsm2/fcs/focs-length/" title="Efficiently Computing the Length of a List" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/" display-uri="focs-length" type="local"><fr:tex display="inline"><![CDATA[\texttt {length}]]></fr:tex> on lists</fr:link>.  Here is a third
measure of a tree’s size:</html:p>
                    <html:pre><![CDATA[# let rec leaves = function
  | Lf -> 1
  | Br (v, t1, t2) -> leaves t1 + leaves t2
val leaves : 'a tree -> int = <fun>]]></html:pre>
                    <html:p>This function is redundant because of a basic fact about trees, which can be
proved by induction: for every tree <fr:tex display="inline"><![CDATA[t]]></fr:tex>, we have <fr:tex display="inline"><![CDATA[\texttt {leaves}(t) =
\texttt {count}(t)+1]]></fr:tex>.  The inequality shown on the slide also has an elementary
proof by induction.</html:p>
                    <html:p>A tree of depth 20 can store <fr:tex display="inline"><![CDATA[2^{20}-1]]></fr:tex> or approximately one million elements.
The access paths to these elements are short, particularly when compared with
a million-element list!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/</fr:uri>
                    <fr:display-uri>focs-binary-trees</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-binary-trees/</fr:route>
                    <fr:title text="Binary Trees, a Recursive Datatype">Binary Trees, a Recursive Datatype</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a tree =
    Lf
  | Br of 'a * 'a tree * 'a tree
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmihauytafmmc5evdkkihzsaxper2thnogxohktuubaoxtrpw24qazu.svg" />
                    </html:figure>
                    <html:pre><![CDATA[# Br(1, Br(2, Br(4, Lf, Lf),
              Br(5, Lf, Lf)),
        Br(3, Lf, Lf))
- : int tree = Br (1, Br (2, Br (4, Lf, Lf), Br (5, Lf, Lf)), Br (3, Lf, Lf))]]></html:pre>
                    <html:p>A data structure with multiple branching is called a “tree”.  Trees can
represent mathematical expressions, logical formulae, computer programs, the
phrase structure of English sentences, etc.</html:p>
                    <html:p><html:em>Binary trees</html:em> are nearly as fundamental as lists.  They can provide
efficient storage and retrieval of information.  In a binary tree, each node
is empty (<fr:tex display="inline"><![CDATA[Lf]]></fr:tex>), or is a branch (<fr:tex display="inline"><![CDATA[Br]]></fr:tex>) with a label and two subtrees.</html:p>
                    <html:p><fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">OCaml lists</fr:link> are a <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> and could be declared as follows:</html:p>
                    <html:pre><![CDATA[# type 'a mylist =
  | Nil
  | Cons of 'a * 'a mylist
type 'a mylist = Nil | Cons of 'a * 'a mylist]]></html:pre>
                    <html:p>We could even declare <html:code>::</html:code> as an infix constructor.  The only
thing we could not define is the <html:code>[...]</html:code> notation, which is
part of the OCaml grammar (although there does exist a mechanism
to use a <html:em>similar</html:em> syntax for custom indexed datatypes).</html:p>
                    <html:p>A <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> type does not have to be <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.
For example, here is a simple datatype of tree shapes with no attached data
that is recursive but not polymorphic.</html:p>
                    <html:pre><![CDATA[# type shape =
  | Null
  | Join of shape * shape
type shape = Null | Join of shape * shape]]></html:pre>
                    <html:p>The datatype <html:code>'a option</html:code> (<fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">mentioned above</fr:link>) is the opposite – it is
polymorphic, but not recursive.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/</fr:uri>
                    <fr:display-uri>focs-zip</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-zip/</fr:route>
                    <fr:title text="Building a List of Pairs">Building a List of Pairs</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec zip xs ys =
    match xs, ys with
    | (x::xs, y::ys) -> (x, y) :: zip xs ys
    | _ -> []
val zip : 'a list -> 'b list -> ('a * 'b) list = <fun>]]></html:pre>
                    <fr:tex display="block"><![CDATA[\left .[x_1,\ldots ,x_n]\atop 
         [y_1,\ldots ,y_n]\right \}\;\longmapsto \;[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex>
                    <html:p>The <html:em>wildcard</html:em> pattern <html:code>_</html:code> matches <html:em>anything</html:em>. We could have written a
variable such as <html:code>p</html:code> instead, but the wildcard reminds us that the
relevant clause ignores this argument.</html:p>
                    <html:p>The patterns are also tested in order of their definitions: first
<html:code>(x::xs, y::ys)</html:code>, then <html:code>_</html:code>.</html:p>
                    <html:p>A list of pairs of the form <fr:tex display="inline"><![CDATA[[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex> associates each
<fr:tex display="inline"><![CDATA[x_i]]></fr:tex> with <fr:tex display="inline"><![CDATA[y_i]]></fr:tex>.  Conceptually, a telephone directory could be regarded as
such a list, where <fr:tex display="inline"><![CDATA[x_i]]></fr:tex> ranges over names and <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> over the corresponding
telephone number.  <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link> in such a list can find the <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> associated
with a given <fr:tex display="inline"><![CDATA[x_i]]></fr:tex>, or vice versa—very slowly.</html:p>
                    <html:p>In other cases, the <fr:tex display="inline"><![CDATA[(x_i,y_i)]]></fr:tex> pairs might have been generated by applying a
function to the elements of another list <fr:tex display="inline"><![CDATA[[z_1,\ldots ,z_n]]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# let rec unzip = function
   | [] -> ([], [])
   | (x, y)::pairs ->
       let xs, ys = unzip pairs in
       (x::xs, y::ys)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>Given a list of pairs, <html:code>unzip</html:code> has to build <html:em>two</html:em> lists of
results, which is awkward using recursion.  The version shown above uses the
<html:em>local binding</html:em> <html:code>let p = </html:code><fr:tex display="inline"><![CDATA[\;E_1\;]]></fr:tex><html:code> in </html:code><fr:tex display="inline"><![CDATA[\;E_2]]></fr:tex>,
where the value of <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> is bound to the variable <html:code>p</html:code> within <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>. The
let-construct counts as an expression and can be used (perhaps wrapped
within parentheses) wherever an expression is expected.</html:p>
                    <html:p>Note especially the phrase <html:code>let xs, ys = unzip pairs</html:code>
which binds <html:code>xs</html:code> and <html:code>ys</html:code> to the results of the recursive call.
In general, the phrase <html:code>let P = E</html:code> matches the
pattern <fr:tex display="inline"><![CDATA[P]]></fr:tex> against the value of expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It binds all the variables
in <fr:tex display="inline"><![CDATA[P]]></fr:tex> to the corresponding values.</html:p>
                    <html:p>The functions <html:code>zip</html:code> and <html:code>unzip</html:code> build and take apart lists of
pairs: <html:code>zip</html:code> pairs up corresponding list elements and <html:code>unzip</html:code>
inverts this operation.  Their types reflect what they do:</html:p>
                    <html:pre><![CDATA[# zip
- : 'a list -> 'b list -> ('a * 'b) list = <fun>
# unzip
- : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>If the lists are of unequal length, <html:code>zip</html:code> discards surplus items at the
end of the longer list.  Its first pattern only matches a pair of non-empty
lists.  The second pattern is just a wildcard and could match anything.  OCaml
tries the clauses in the order given, so the first pattern is tried first.
The second only gets arguments where at least one of the lists is empty.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-unzip/</fr:uri>
                    <fr:display-uri>focs-unzip</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-unzip/</fr:route>
                    <fr:title text="Building a Pair of Results">Building a Pair of Results</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Here is a version of <html:code>unzip</html:code> that replaces the local declaration by a
function <html:code>conspair</html:code> for taking apart the pair of lists in the
recursive call.  It defines the same
computation as the previous version of <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local"><html:code>unzip</html:code></fr:link> and is possibly clearer,
but not every local binding can be eliminated as easily.</html:p>
                    <html:pre><![CDATA[# let conspair ((x, y), (xs, ys)) = (x::xs, y::ys)
val conspair : ('a * 'b) * ('a list * 'b list) -> 'a list * 'b list = <fun>
# let rec unzip = function
    | [] -> ([], [])
    | xy :: pairs -> conspair (xy, unzip pairs)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>Making the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> yields <html:code>revUnzip</html:code> below, which is
very simple.  Iteration can construct many results at once in different
argument positions.  Both output lists are built in reverse order, which can
be corrected by reversing the input to <html:code>revUnzip</html:code>.  The total costs
will probably exceed those of <html:code>unzip</html:code> despite the advantages of
iteration.</html:p>
                    <html:pre><![CDATA[# let rec revUnzip = function
    | ([], xs, ys) -> (xs, ys)
    | ((x, y)::pairs, xs, ys) ->
        revUnzip (pairs, x::xs, y::ys)
val revUnzip : ('a * 'b) list * 'a list * 'b list -> 'a list * 'b list =
  <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nlength/</fr:uri>
                    <fr:display-uri>focs-nlength</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nlength/</fr:route>
                    <fr:title text="Computing the Length of a List">Computing the Length of a List</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nlength = function
  | [] -> 0
  | x :: xs -> 1 + nlength xs
val nlength : 'a list -> int = <fun>
# nlength []
- : int = 0
# nlength [5; 6; 7]
- : int = 3]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nlength }[a; b; c] \Rightarrow  &\; 1 + \text {nlength }[b; c] \\
   \Rightarrow  &\; 1 + (1 + \text {nlength }[c]) \\
   \Rightarrow  &\; 1 + (1 + (1 + \text {nlength }[])) \\
   \Rightarrow  &\; 1 + (1 + (1 + 0)) \\
   \Rightarrow  &\; \ldots  \;\; 3
\end {aligned}
]]></fr:tex>
                    <html:p>Most list processing involves <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  This is a simple example; patterns
can be more complex.  Observe the use of a vertical bar <html:code>|</html:code> to separate the function’s
clauses.  We have <html:em>one</html:em> function declaration that handles two cases.
To understand its role, consider the following faulty code:</html:p>
                    <html:pre><![CDATA[# let rec nlength [] = 0
Line 1, characters 17-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
_::_
val nlength : 'a list -> int = <fun>
# let rec nlength (x::xs) = 1 + nlength xs
Line 1, characters 17-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val nlength : 'a list -> int = <fun>]]></html:pre>
                    <html:p>These are two declarations, not one.  First we declare <html:code>nlength</html:code> to be a
function that handles only empty lists.  Then we redeclare it to be a function
that handles only non-empty lists; it can never deliver a result.  We see that
a second <html:code>let</html:code> declaration replaces any previous one rather than extending it
to cover new cases.</html:p>
                    <html:p>Now, let us return to our original declaration of <html:code>nlength</html:code>.  The length function
is <html:em><fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link></html:em> and applies to <html:em>all</html:em> lists regardless of element
type!  Most programming languages lack such flexibility.</html:p>
                    <html:p>Unfortunately, this length computation is naive and wasteful.  Like
<fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> earlier, it is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail-recursive</fr:link>.  It
uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its input.  As usual, the
solution is to add an accumulating argument.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/</fr:uri>
                    <fr:display-uri>focs-seq-consume</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-consume/</fr:route>
                    <fr:title text="Consuming a Sequence">Consuming a Sequence</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec get n s =
    match n, s with
    | 0, _            -> []
    | n, Nil          -> []
    | n, Cons (x, xf) -> x :: get (n-1) (xf ())
val get : int -> 'a seq -> 'a list = <fun>]]></html:pre>
                    <html:p>The above code gets the first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements as a list.
<html:code>xf ()</html:code> <html:em>forces</html:em> evaluation.</html:p>
                    <html:p>The function <html:code>get</html:code> converts a sequence to a list.  It takes the
first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements; it takes all of them if <fr:tex display="inline"><![CDATA[n<0]]></fr:tex>, which can terminate only if
the sequence is finite.</html:p>
                    <html:p>In the last line of <html:code>get</html:code>, the expression <html:code>xf()</html:code> calls the tail
function, demanding evaluation of the next element.  This operation is called
<html:em>forcing</html:em> the sequence.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/</fr:uri>
                    <fr:display-uri>focs-length</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-length/</fr:route>
                    <fr:title text="Efficiently Computing the Length of a List">Efficiently Computing the Length of a List</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec addlen n = function
  | []    -> n
  | x::xs -> addlen (n + 1) xs
val addlen : int -> 'a list -> int = <fun>
# addlen 0 [5; 6; 7]
- : int = 3]]></html:pre>
                    <html:p>Recall that the use of <html:code>function</html:code> introduces an extra (unnamed) argument
that is <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matched</fr:link> in the subsequent clauses; in this case, to break
open the list.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {addlen }0 [a; b; c] \Rightarrow  &\;  \text {addlen }1\;[b; c] \\
  \Rightarrow   &\; \text {addlen }2\;[c] \\
  \Rightarrow   &\; \text {addlen }3\;[] \\
  \Rightarrow   &\; 3
\end {aligned}
]]></fr:tex>
                    <html:p>Function <html:code>addlen</html:code> is again <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.  Its type mentions the integer
accumulator.</html:p>
                    <html:p>Now we may declare an efficient length function.  It is simply a wrapper for
<html:code>addlen</html:code>, supplying zero as the initial value of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# let length xs = addlen 0 xs
val length : 'a list -> int = <fun>
# length [5; 6; 7; 8]
- : int = 4]]></html:pre>
                    <html:p>The recursive calls do not nest: this version is <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It takes <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
space.  Obviously its time requirement is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> because it takes at least <fr:tex display="inline"><![CDATA[n]]></fr:tex>
steps to find the length of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/</fr:uri>
                    <fr:display-uri>focs-power</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-power/</fr:route>
                    <fr:title text="Efficiently Raising a Number to a Power">Efficiently Raising a Number to a Power</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec power x n =
    if n = 1 then x
    else if even n then
      power (x *. x) (n / 2)
    else
      x *. power (x *. x) (n / 2)
val power : float -> int -> float = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Mathematical Justification</html:em>
                    </html:p>
                    <fr:tex display="block"><![CDATA[\begin {aligned}
           x^1 & = x \\
           x^{2n} & = (x^2)^n  \\
           x^{2n+1} & = x\times (x^2)^n.
\end {aligned}]]></fr:tex>
                    <html:p>For large <html:code>n</html:code>, computing powers using <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> is too slow to
be practical.  The equations above are much faster. Example:</html:p>
                    <fr:tex display="block"><![CDATA[ 2^{12} = 4^6 = 16^3 = 16\times  256^1 = 16\times  256 = 4096. ]]></fr:tex>
                    <html:p>Instead of <html:code>n</html:code> multiplications, we need at most <fr:tex display="inline"><![CDATA[2\lg  n]]></fr:tex> multiplications,
where <fr:tex display="inline"><![CDATA[\lg  n]]></fr:tex> is the logarithm of <fr:tex display="inline"><![CDATA[n]]></fr:tex> to the base <fr:tex display="inline"><![CDATA[2]]></fr:tex>.</html:p>
                    <html:p>We use the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>even</html:code></fr:link>, declared previously, to test whether the
exponent is even.  Integer division (<html:code>/</html:code>) truncates its result to an
integer: dividing <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex> by 2 yields <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>A recurrence is a useful computation rule only if it is bound to terminate.
If <fr:tex display="inline"><![CDATA[n>0]]></fr:tex> then <fr:tex display="inline"><![CDATA[n]]></fr:tex> is smaller than both <fr:tex display="inline"><![CDATA[2n]]></fr:tex> and <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex>.  After enough
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive calls</fr:link>, the exponent will be reduced to <fr:tex display="inline"><![CDATA[1]]></fr:tex>.  The equations also hold
if <fr:tex display="inline"><![CDATA[n\leq 0]]></fr:tex>, but the corresponding computation runs forever.</html:p>
                    <html:p>Our reasoning assumes arithmetic to be <html:em>exact</html:em>. Fortunately, the calculation is
well-behaved using floating-point.</html:p>
                    <html:p>Computer numbers have a finite range, which if exceeded results in the
integer wrapping around.  You will understand this behaviour more as you
learn about computer architecture and how modern systems represent
numbers in memory.</html:p>
                    <html:p>If integers and floats must be combined in a calculation, OCaml provides functions
to convert between them:</html:p>
                    <html:pre><![CDATA[# int_of_float 3.14159
- : int = 3
# float_of_int 3
- : float = 3.]]></html:pre>
                    <html:p>OCaml’s libraries are organised using “modules”, so we may use compound
identifiers such as <html:code>Float.of_int</html:code> to refer to library functions. There
are many thousands of library functions available in the OCaml ecosystem,
including text-processing and operating systems functions in addition to the
usual numerical ones.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/</fr:uri>
                    <fr:display-uri>focs-tree-traversal-efficient</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal-efficient/</fr:route>
                    <fr:title text="Efficiently Traversing Trees">Efficiently Traversing Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Unfortunately, the functions shown on the previous slide are quadratic in the
worst case: the appends in the recursive calls are inefficient.  To correct
that problem, we (as usual) add an accumulating argument.  Observe how
each function constructs its result list and compare with how appends were
eliminated from <html:code>quicksort</html:code> in the <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">Sorting lecture</fr:link>.</html:p>
                    <html:pre><![CDATA[# let rec preord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      v :: preord (t1, preord (t2, vs))
val preord : 'a tree * 'a list -> 'a list = <fun>
# let rec inord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      inord (t1, v::inord (t2, vs))
val inord : 'a tree * 'a list -> 'a list = <fun>
# let rec postord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      postord (t1, postord (t2, v::vs))
val postord : 'a tree * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>One can prove equations relating each of these functions to its counterpart on
the previous section.  For example:</html:p>
                    <fr:tex display="block"><![CDATA[\texttt {inord}(t, vs) = \texttt {inorder}(t) @ vs]]></fr:tex>
                    <html:p>These three types of tree traversal are related in that all are depth-first.
They each traverse the left subtree in full before traversing the right
subtree.  Breadth-first search (from the <fr:link href="/~avsm2/fcs/focs-queues/" title="Queues and Search Strategies" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queues/" display-uri="focs-queues" type="local">Queues lecture</fr:link>) is another
possibility.  That involves going through the levels of a tree one at a time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-expression-evaluation/</fr:uri>
                    <fr:display-uri>focs-expression-evaluation</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-expression-evaluation/</fr:route>
                    <fr:title text="Expression Evaluation">Expression Evaluation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Expression evaluation concerns expressions and the values they return. This
view of computation may seem to be too narrow. It is certainly far removed from
computer hardware, but that can be seen as an advantage. For the traditional
concept of computing solutions to problems, expression evaluation is entirely
adequate.</html:p>
                    <html:p>Starting with <fr:tex display="inline"><![CDATA[E_0]]></fr:tex>, the expression <fr:tex display="inline"><![CDATA[E_i]]></fr:tex> is reduced to <fr:tex display="inline"><![CDATA[E_{i+1}]]></fr:tex> until this
process concludes with a value <fr:tex display="inline"><![CDATA[v]]></fr:tex>.  A <html:em>value</html:em> is something like a number
that cannot be further reduced.</html:p>
                    <html:p>We write <fr:tex display="inline"><![CDATA[E \rightarrow  E']]></fr:tex> to say that <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:em>reduced</html:em> to <fr:tex display="inline"><![CDATA[E']]></fr:tex>.
Mathematically, they are equal: <fr:tex display="inline"><![CDATA[E=E']]></fr:tex>, but the computation goes from <fr:tex display="inline"><![CDATA[E]]></fr:tex> to
<fr:tex display="inline"><![CDATA[E']]></fr:tex> and never the other way around.</html:p>
                    <html:p>Computers also interact with the outside world.  For a start, they need some
means of accepting problems and delivering solutions.  Many computer systems
monitor and control industrial processes.  This role of computers is familiar
now, but was never envisaged in the early days. Computer pioneers focused on
mathematical calculations.  Modelling interaction and control requires a notion
of <html:em>states</html:em> that can be observed and changed.  Then we can consider
updating the state by assigning to variables or performing input/output,
finally arriving at conventional programs as coded in C, for instance.</html:p>
                    <html:p>For now, we remain at the level of expressions, which is usually termed
<html:em>functional programming</html:em>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/</fr:uri>
                    <fr:display-uri>focs-insertion-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-insertion-sort/</fr:route>
                    <fr:title text="Insertion Sort">Insertion Sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An insert operation does <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> comparisons on average.</html:p>
                    <html:pre><![CDATA[# let rec ins x = function
    | [] -> [x]
    | y::ys -> if x <= y then x :: y :: ys
               else y :: ins x ys
val ins : 'a -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Insertion sort</html:em> takes <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons on average:</html:p>
                    <html:pre><![CDATA[let rec insort = function
    | [] -> []
    | x::xs -> ins x (insort xs)]]></html:pre>
                    <html:p>Items from the input are copied one at a time to the output.  Each new item is
inserted into the right place so that the output is always in order.</html:p>
                    <html:p>We could easily write <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> versions of these functions, but to no purpose.
Insertion sort is slow because it does <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons (and a lot of list
copying), not because it is recursive.  Its quadratic runtime makes it nearly
useless: it takes 174 seconds for our example while the next-worst figure is
1.4 seconds.</html:p>
                    <html:p>Insertion sort is worth considering because it is easy to code and illustrates
the concepts.  Two efficient sorting algorithms, <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link> and heapsort, can be
regarded as refinements of insertion sort.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/</fr:uri>
                    <fr:display-uri>focs-while</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-while/</fr:route>
                    <fr:title text="Iteration: the while command">Iteration: the while command</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let tlopt = function
  | [] -> None
  | _::xs -> Some xs
val tlopt : 'a list -> 'a list option = <fun>
# let length xs =
    let lp  = ref xs in (* list of uncounted elements *)
    let np  = ref 0  in (* accumulated count *)
    let fin = ref false in
    while not !fin do
      match tlopt !lp with
      | None -> fin := true
      | Some xs ->
          lp := xs;
          np := 1 + !np
    done;
    !np (* the final count is returned *)
val length : 'a list -> int = <fun>]]></html:pre>
                    <html:p>Once we can change the state, we need to do so repeatedly.  <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">Recursion</fr:link> can
serve this purpose, but having to declare a procedure for every loop is
clumsy, and compilers for conventional languages seldom exploit
<fr:link href="/~avsm2/fcs/focs-recursion-vs-iteration/" title="Recursion vs Iteration" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/" display-uri="focs-recursion-vs-iteration" type="local">tail-recursion</fr:link>.</html:p>
                    <html:p>Early programming languages provided little support for repetition.  The
programmer had to set up loops using goto commands, exiting the loop using
another goto controlled by an <html:code>if</html:code>.  Modern languages provide a
confusing jumble of looping constructs, the most fundamental of which is
<html:code>while B do C</html:code>.  The boolean expression <fr:tex display="inline"><![CDATA[B]]></fr:tex> is evaluated,
and if true, command <fr:tex display="inline"><![CDATA[C]]></fr:tex> is executed and the command repeats.  If <fr:tex display="inline"><![CDATA[B]]></fr:tex>
evaluates to false then the <html:code>while</html:code> command terminates, perhaps without
executing <fr:tex display="inline"><![CDATA[C]]></fr:tex> even once.</html:p>
                    <html:p>OCaml’s main looping construct is <html:code>while</html:code>, which returns the value <html:code>()</html:code>.  The
function <html:code>length</html:code> declares <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> to hold the list under
examination (<html:code>lp</html:code>) and number of elements counted so far (<html:code>np</html:code>) as well
as whether the end of the list has been reached (the boolean reference <html:code>fin</html:code>).
While the list is non-empty, we skip over one more element (by setting it to
its tail) and count that element.</html:p>
                    <html:p>The body of the <html:code>while</html:code> loop first checks to see if the end of the list has
been reached, in which case it sets the <html:code>fin</html:code> variable to true.  If there is a
tail value, then two assignments are executed in sequence.  The <html:code>lp</html:code> reference
is set to the tail of the list, and the <html:code>np</html:code> reference integer is incremented
by one.  When the while loop terminates due to the <html:code>fin</html:code> variable being set to
true, the expression <html:code>!np</html:code> returns the computed length as the function’s
result.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/</fr:uri>
                    <fr:display-uri>focs-summing-iter</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-summing-iter/</fr:route>
                    <fr:title text="Iteratively summing the first n integers">Iteratively summing the first n integers</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec summing n total =
    if n = 0 then
      total
    else
      summing (n - 1) (n + total)
val summing : int -> int -> int = <fun>]]></html:pre>
                    <html:p>Function <html:code>summing</html:code> takes an additional argument: a running total.  If
<html:code>n</html:code> is zero then it returns the running total; otherwise, <html:code>summing</html:code>
adds to it and continues.  The recursive calls do not nest; the additions are
done immediately.</html:p>
                    <html:p>A recursive function whose computation does not nest is called
<html:em>iterative</html:em> or <html:em>tail-recursive</html:em>. Many functions can be made iterative by
introducing an argument analogous to <html:code>total</html:code>, which is often called an
<html:em>accumulator</html:em>.</html:p>
                    <html:p>The gain in efficiency is sometimes worthwhile and sometimes not.  The function
<fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> is not iterative because nesting occurs whenever the exponent is odd.
Adding a third argument makes it iterative, but the change complicates the
function and the gain in efficiency is minute; for 32-bit integers, the maximum
possible nesting is 30 for the exponent <fr:tex display="inline"><![CDATA[2^{31}-1]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-append/</fr:uri>
                    <fr:display-uri>focs-seq-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-append/</fr:route>
                    <fr:title text="Joining Two Sequences">Joining Two Sequences</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec appendq xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons(x, fun () -> appendq (xf ()) yq)
val appendq : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>A more fair alternative:</html:p>
                    <html:pre><![CDATA[# let rec interleave xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons (x, fun () -> interleave yq (xf ()))
val interleave : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>Most list functions and <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> have analogues on sequences, but strange
things can happen.  Can an infinite list be reversed?</html:p>
                    <html:p>Function <html:code>appendq</html:code> is precisely the same idea as <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>
from the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">Lists lecture</fr:link>; it concatenates two sequences.  If the first
argument is infinite, then <html:code>appendq</html:code> never gets to its second argument,
which is lost.  Concatenation of infinite sequences is not terribly
interesting.</html:p>
                    <html:p>The function <html:code>interleave</html:code> avoids this problem by exchanging the two
arguments in each recursive call.  It combines the two <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, losing no
elements.  Interleaving is the right way to combine two potentially infinite
information sources into one.</html:p>
                    <html:p>In both function declarations, observe that each <html:code>xf ()</html:code> is enclosed
within a <fr:tex display="inline"><![CDATA[{\tt  fun () \rightarrow  \ldots }]]></fr:tex>.  Each <html:em>force</html:em> is enclosed within a
<html:em>delay</html:em>.  This practice makes the functions lazy.  A force not enclosed
in a delay, as in <fr:link href="/~avsm2/fcs/focs-seq-consume/" title="Consuming a Sequence" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/" display-uri="focs-seq-consume" type="local"><html:code>get</html:code></fr:link> above, runs the risk of evaluating the sequence
in full.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/</fr:uri>
                    <fr:display-uri>focs-take-drop</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-take-drop/</fr:route>
                    <fr:title text="List Utilities: take and drop">List Utilities: take and drop</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This lecture examines more list utilities, illustrating more patterns of
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, and concludes with a small program for <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.</html:p>
                    <html:p>The functions <html:code>take</html:code> and <html:code>drop</html:code> divide a list
into parts, returning or discarding the first <fr:tex display="inline"><![CDATA[i]]></fr:tex> elements.</html:p>
                    <fr:tex display="block"><![CDATA[xs = [\underbrace {x_0,\ldots ,x_{i-1}}_{\text {take i xs}},
      \underbrace {x_i,\ldots ,x_{n-1}}_{\text {drop i xs}} ]]]></fr:tex>
                    <html:p>They can be implemented in OCaml as follows:</html:p>
                    <html:pre><![CDATA[# let rec take i = function
    | [] -> []
    | x::xs ->
        if i > 0 then x :: take (i - 1) xs
        else []
val take : int -> 'a list -> 'a list = <fun>
# let rec drop i = function
    | [] -> []
    | x::xs ->
        if i > 0 then drop (i-1) xs
        else x::xs
val drop : int -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Applications of <html:code>take</html:code> and <html:code>drop</html:code> will appear in future lectures.  Typically,
they divide a collection of items into equal parts for recursive processing.</html:p>
                    <html:p>The <html:code>take</html:code> function is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>, but making it so would not improve
its efficiency.  The task requires copying up to <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements, which must
take <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> space and time.</html:p>
                    <html:p>Function <html:code>drop</html:code> simply skips over <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements.  This requires
<fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time but only constant space.  It is iterative and much faster than
<html:code>take</html:code>.  Both functions use <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time, but skipping elements is faster
than copying them:  <html:code>drop</html:code>’s constant factor is smaller.</html:p>
                    <html:p>Both functions take an integer and a list, returning a list of the same type.
So their type is <html:code>int -&gt; 'a list -&gt; 'a list</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/</fr:uri>
                    <fr:display-uri>focs-change-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-exceptions/</fr:route>
                    <fr:title text="Making Change with Exceptions">Making Change with Exceptions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Change
  let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise Change
    | c::till, amt -> if amt < 0 then raise Change
                      else try c :: change (c::till) (amt - c)
                           with Change -> change till amt
exception Change
val change : int list -> int -> int list = <fun>]]></html:pre>
                    <html:p>In the <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">Lists lectures</fr:link>, we considered the problem of <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.  The greedy
algorithm presented there could not express “6 using 5 and 2” because it always
took the largest coin.  Returning <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">the list of all possible solutions</fr:link> avoids
that problem rather expensively: we only need one solution.</html:p>
                    <html:p>Using <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>, we can code a <html:em>backtracking</html:em> algorithm: one that can undo
past decisions if it comes to a dead end.  The exception <html:code>Change</html:code> is raised if
we run out of coins (with a non-zero amount) or if the amount goes negative.
We always try the largest coin, but enclose the recursive call in an exception
handler, which undoes the choice if it goes wrong.</html:p>
                    <html:p>Carefully observe how exceptions interact with <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  The exception
handler always undoes the <html:em>most recent</html:em> choice, leaving others possibly to
be undone later.  If making change really is impossible, then eventually
<html:code>exception Change</html:code> will be raised with no handler to catch it, and it
will be reported at top level.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-trace/</fr:uri>
                    <fr:display-uri>focs-change-trace</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-trace/</fr:route>
                    <fr:title text="Making Change: A Trace">Making Change: A Trace</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Here is the full execution. Observe how the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception handlers</fr:link> nest and how
they drop away once the given expression has returned a value.</html:p>
                    <fr:tex display="block"><![CDATA[\begin{aligned}
\text{change [5; 2] 6}
  \Rightarrow &\; \text{try 5::change [5; 2] 1}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 5::change [5; 2] (-4)}\\
              &\; \text{with Change -> change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{5::(change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 2::change [2] (-1)}\\
              &\; \text{with Change -> change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{try 5::(change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{change [2] 6} \\
  \Rightarrow &\; \text{try 2::change [2] 4}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::change [2] 2}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::(try 2::change [2] 0 }\\
              &\; \text{with Change -> change [] 2)}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::[2]}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::[2; 2]}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{[2; 2; 2]}
\end{aligned}]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge/</fr:uri>
                    <fr:display-uri>focs-merge</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge/</fr:route>
                    <fr:title text="Merging Two Lists">Merging Two Lists</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Merge joins two sorted lists.</html:p>
                    <html:pre><![CDATA[# let rec merge = function
    | [], ys -> ys
    | xs, [] -> xs
    | x::xs, y::ys ->
        if x <= y then
          x :: merge (xs, y::ys)
        else
          y :: merge (x::xs, ys)
val merge : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Generalises <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insert</fr:link> to two lists, and does at most <fr:tex display="inline"><![CDATA[m+n-1]]></fr:tex> comparisons.</html:p>
                    <html:p><html:em>Merging</html:em> means combining two sorted lists to form a larger sorted list.
It does at most <fr:tex display="inline"><![CDATA[m+n]]></fr:tex> comparisons, where <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are the lengths of the
input lists.  If <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are roughly equal then we have a fast way of
constructing sorted lists; if <fr:tex display="inline"><![CDATA[n=1]]></fr:tex> then merging degenerates to insertion,
doing much work for little gain.</html:p>
                    <html:p>Merging is the basis of several sorting algorithms; we look at a
divide-and-conquer one.  Mergesort is seldom found in conventional programming
because it is hard to code for arrays; it works nicely with lists.  It divides
the input (if non-trivial) into two roughly equal parts, sorts them
recursively, then merges them.</html:p>
                    <html:p>Function <html:code>merge</html:code> is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>; the recursion is deep.  An iterative
version is of little benefit for the same reasons that apply to
<fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link> in the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">earlier lecture on Lists</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/</fr:uri>
                    <fr:display-uri>focs-quicksort-idea</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort-idea/</fr:route>
                    <fr:title text="Quicksort: The Idea">Quicksort: The Idea</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The Quicksort algorithm has the following flow:</html:p>
                    <html:ul><html:li>Choose a <html:em>pivot</html:em> element, <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li>
  <html:li>Divide to partition the input into two sublists:
    <html:ul><html:li>those <html:em>at most</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex> in value</html:li>
      <html:li>those <html:em>exceeding</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li></html:ul></html:li>
  <html:li>Conquer using recursive calls to sort the sublists</html:li>
  <html:li>Combine the sorted lists by appending one to the other</html:li></html:ul>
                    <html:p>Quicksort was invented by Sir Anthony Hoare, who works at Microsoft Research,
Cambridge.  Quicksort works by <html:em>divide and conquer,</html:em> a basic algorithm design
principle.  Quicksort chooses from the input some value <fr:tex display="inline"><![CDATA[a]]></fr:tex>, called the
<html:em>pivot</html:em>.  It partitions the remaining items into two parts: those <fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>, and
those <fr:tex display="inline"><![CDATA[>a]]></fr:tex>.  It sorts each part recursively, then puts the smaller part before
the greater.</html:p>
                    <html:p>The cleverest feature of Hoare's algorithm was that the partition could be done
<html:em>in place</html:em> by exchanging array elements.  Quicksort was invented before
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> was well known, and people found it extremely hard to understand.  As
usual, we shall consider a list version based on functional programming.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/</fr:uri>
                    <fr:display-uri>focs-npower</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-npower/</fr:route>
                    <fr:title text="Raising a Number to a Power">Raising a Number to a Power</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec npower x n =
    if n = 0 then 1.0
    else x *. npower x (n - 1)
val npower : float -> int -> float = <fun>]]></html:pre>
                    <html:p>Our new <html:code>npower</html:code> definition can now take additional arguments, reflected in the arrows
present in the type of <html:code>npower</html:code>; these represent <html:em>parameters</html:em> that can be passed to the
new value being defined, with the final segment being the resulting type. Thus our <html:code>npower</html:code>
type can be read as "pass in a float and integer to return a float".</html:p>
                    <html:p><html:em>Mathematical Justification</html:em> (for <fr:tex display="inline"><![CDATA[x\not =0]]></fr:tex>):</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
           x^0 & = 1 \\
           x^{n+1} & = x\times  x^n.
\end {aligned}
]]></fr:tex>
                    <html:p>The function <html:code>npower</html:code> raises its float argument <html:code>x</html:code> to the power <html:code>n</html:code>, a
non-negative integer. The function is <html:strong>recursive</html:strong>: it calls itself.  You
can spot a recursive function due to the <html:code>rec</html:code> keyword in the definition:
this indicates that any invocation of the function name within the function body should call itself.
This concept should be familiar from mathematics, since exponentiation is defined by the
rules shown above. You may also have seen recursion in the product rule for
differentiation: <fr:tex display="inline"><![CDATA[(u\cdot  v)' = u\cdot  v' + u'\cdot  v]]></fr:tex>. In finding the derivative of <fr:tex display="inline"><![CDATA[u\cdot  v]]></fr:tex>,
we recursively find the derivatives of <fr:tex display="inline"><![CDATA[u]]></fr:tex> and <fr:tex display="inline"><![CDATA[v]]></fr:tex>, combining them to obtain the desired result.
The recursion is meaningful because it terminates: we reduce the problem to two smaller
problems, and this cannot go on forever. The OCaml programmer uses recursion
heavily.  For <fr:tex display="inline"><![CDATA[n\geq 0]]></fr:tex>, the equation <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> yields an obvious
computation:</html:p>
                    <fr:tex display="block"><![CDATA[ x^3 = x\times  x^2 = x\times  x\times  x^1 = x\times  x\times  x\times  x^0 = x\times  x\times  x ]]></fr:tex>
                    <html:p>The equation clearly holds even for negative <fr:tex display="inline"><![CDATA[n]]></fr:tex>. However, the corresponding
computation runs forever:</html:p>
                    <fr:tex display="block"><![CDATA[ x^{-1} = x\times  x^{-2} = x\times  x\times  x^{-3}=\cdots  ]]></fr:tex>
                    <html:p>Note that the function <html:code>npower</html:code> contains both an integer constant (<html:code>0</html:code>) and a
floating point constant (<html:code>1.0</html:code>). The decimal point makes all the difference.
OCaml will notice and ascribe different meaning to each type of constant.</html:p>
                    <html:pre><![CDATA[# let square x = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>Now for a tiresome but necessary aside. In most languages, the types of
arguments and results must always be specified. OCaml is unusual that it normally
infers the types itself. However, sometimes it is useful to supply a hint to
help you debug and develop your program. OCaml will still infer the types even if you don’t specify them, but in some cases
it will use a more inefficient function than a specialised one. Some languages
have just one type of number, converting automatically between different
formats; this is slow and could lead to unexpected rounding errors.  Type
constraints are allowed almost anywhere. We can put one on any occurrence of x
in the function.</html:p>
                    <html:pre><![CDATA[# let square (x : float) = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>Or we can constrain the type of the function’s result:</html:p>
                    <html:pre><![CDATA[# let square x : float = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>OCaml treats the equality and comparison test specially. Expressions like <html:code>if x = y then</html:code> …
are allowed provided <html:code>x</html:code> and <html:code>y</html:code> have the same type and equality testing is
possible for that type. (We discuss <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local">equality</fr:link> further in a later lecture.)
Note that <html:code>x &lt;&gt; y</html:code> is OCaml for <fr:tex display="inline"><![CDATA[x\not =y]]></fr:tex>.</html:p>
                    <html:p>A characteristic feature of the computer is its ability to test for conditions
and act accordingly.  In the early days, a program might jump to a given
address depending on the sign of some number.  Later, John McCarthy defined
the <html:em>conditional expression</html:em> to satisfy <html:code>if true then x else y = x</html:code> and
<html:code>if false then x else y = y</html:code>.</html:p>
                    <html:p>OCaml evaluates the expression <html:code>if</html:code> <fr:tex display="inline"><![CDATA[B]]></fr:tex> <html:code>then</html:code> <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> <html:code>else</html:code> <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> by first evaluating <fr:tex display="inline"><![CDATA[B]]></fr:tex>.
If the result is <html:code>true</html:code> then OCaml evaluates <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and otherwise <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>.  Only one
of the two expressions <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> is evaluated!  If both were evaluated,
then recursive functions like <html:code>npower</html:code> above would run forever.</html:p>
                    <html:p>The <html:code>if</html:code>-expression is governed by an expression of type <html:code>bool</html:code>, whose two
values are <html:code>true</html:code> and <html:code>false</html:code>.  In modern programming languages, tests are not
built into “conditional branch” constructs but can just be part of normal expressions.
Tests, or <html:em>Boolean expressions,</html:em> can be expressed using relational operators
such as <html:code>&lt;</html:code> and <html:code>=</html:code>. They can be combined using the Boolean operators for
negation (<html:code>not</html:code>), conjunction (written as <html:code>&amp;&amp;</html:code>) and disjunction (written as <html:code>||</html:code>).  New
properties can be declared as functions: here, to test whether an integer is
even, for example:</html:p>
                    <html:pre><![CDATA[# let even n = n mod 2 = 0
val even : int -> bool = <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/</fr:uri>
                    <fr:display-uri>focs-def-recursion</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-recursion/</fr:route>
                    <fr:title text="Recursion">Recursion</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A function is recursive if it calls itself. You can spot a recursive function
by the <html:code>rec</html:code> keyword in its definition: this indicates that any invocation
of the function name within the function body should call itself. The recursion
is meaningful because it terminates: we reduce the problem to smaller problems,
and this cannot go on forever.
Introduced in <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local">Raising a Number to a Power</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/</fr:uri>
                    <fr:display-uri>focs-recursion-vs-iteration</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-recursion-vs-iteration/</fr:route>
                    <fr:title text="Recursion vs Iteration">Recursion vs Iteration</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>“Iterative” normally refers to a loop, coded using <html:code>while</html:code> for example (see the <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local">final lecture</fr:link>)</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">Tail-recursion</fr:link> is only efficient if the compiler detects it</html:li>
  <html:li>Mainly it saves space (memory), though iterative code can also run faster</html:li>
  <html:li>Do not make programs iterative unless the gain is worth it</html:li></html:ul>
                    <html:p>A <fr:link href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs" type="external">classic book</fr:link>
by Abelson and Sussman, which describes the Lisp dialect known as Scheme,
used <html:em>iterative</html:em> to mean <html:em>tail-recursive</html:em>. Iterative functions produce computations
resembling those that can be done using while-loops in conventional languages.</html:p>
                    <html:p>Many algorithms can be expressed naturally using <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, but only awkwardly
using iteration. There is a story that Dijkstra sneaked recursion into Algol-60
by inserting the words “any other occurrence of the procedure name denotes
execution of the procedure.” By not using the word “recursion”, he managed to
slip this amendment past sceptical colleagues.</html:p>
                    <html:p>Obsession with tail recursion leads to a coding style in which functions
have many more arguments than necessary.  Write straightforward code first,
avoiding only gross inefficiency.  If the program turns out to be too slow,
tools are available for pinpointing the cause.  Always remember KISS (Keep
It Simple, Stupid).</html:p>
                    <html:p>I hope you have all noticed by now that the summation can be done even more
efficiently using the arithmetic progression formula:</html:p>
                    <fr:tex display="block"><![CDATA[1+\cdots +n = n(n+1)/2]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/</fr:uri>
                    <fr:display-uri>focs-rev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-rev/</fr:route>
                    <fr:title text="Reversing a List in O(n)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec rev_app xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> rev_app xs (x::ys)
val rev_app : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {rev\_app }[a; b; c]\;[] \Rightarrow  &\; \text {rev\_app }[b; c]\; [a] \\
  \Rightarrow  &\; \text {rev\_app }[c]\; [b; a] \\
  \Rightarrow  &\; \text {rev\_app }[]\; [c; b; a] \\
  \Rightarrow  &\; [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>Calling <html:code>rev_app xs ys</html:code> reverses the elements of <html:code>xs</html:code> and
prepends them to <html:code>ys</html:code>.  Now we may declare</html:p>
                    <html:pre><![CDATA[# let rev xs = rev_app xs []
val rev : 'a list -> 'a list = <fun>
# rev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <html:p>It is easy to see that this reverse function performs just <fr:tex display="inline"><![CDATA[n]]></fr:tex> conses, given
an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.  For both reverse functions, we could count the number of
conses precisely—not just up to a constant factor.  <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> is still
useful to describe the overall running time: the time taken by a cons
varies from one system to another.</html:p>
                    <html:p>The accumulator <fr:tex display="inline"><![CDATA[y]]></fr:tex> makes the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  But the gain in complexity
arises from the removal of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.  Replacing an expensive operation (append)
by a series of cheap operations (cons) is called <html:em>reduction in strength</html:em>
and is a common technique in computer science.  It originated when many
computers did not have a hardware multiply instruction; the series of products
<fr:tex display="inline"><![CDATA[i\times  r]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, <fr:tex display="inline"><![CDATA[\ldots , n]]></fr:tex> could more efficiently be computed by
repeated addition.  Reduction in strength can be done in various ways; we
shall see many instances of removing append.</html:p>
                    <html:p>Consing to an accumulator produces the result in reverse.  If
that forces the use of an extra list reversal then the iterative function
may be much slower than the recursive one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nrev/</fr:uri>
                    <fr:display-uri>focs-nrev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nrev/</fr:route>
                    <fr:title text="Reversing a List in O(n^2)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Let us consider one way to reverse a list.</html:p>
                    <html:pre><![CDATA[# let rec nrev = function
  | [] -> []
  | x::xs -> (nrev xs) @ [x]
val nrev : 'a list -> 'a list = <fun>
# nrev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nrev }[a; b; c] \Rightarrow  &\; \text {nrev }[b; c]\;@\;[a] \\
  \Rightarrow  &\;  (\text {nrev }[c]\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  ((\text {nrev }[]\;@\;[c])\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  (([]\;@\;[c])\;@\;[b])\;@\;[a] \ \ldots  \ [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>This reverse function is grossly inefficient due to poor usage of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>, which
copies its first argument.  If <html:code>nrev</html:code> is given a list of length <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>, then
append makes <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> conses to copy the reversed tail.  Constructing the list
<html:code>[x]</html:code> calls <html:code>cons</html:code> again, for a total of <fr:tex display="inline"><![CDATA[n]]></fr:tex> calls.  Reversing the tail
requires <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> more conses, and so forth.  The total number of conses is:</html:p>
                    <fr:tex display="block"><![CDATA[ 0 + 1 + 2 + \cdots  + n = {n(n+1)/2} ]]></fr:tex>
                    <html:p>The time complexity is therefore <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Space complexity is only <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>
because the copies don’t all exist at the same time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-evaluation/</fr:uri>
                    <fr:display-uri>focs-seq-evaluation</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-evaluation/</fr:route>
                    <fr:title text="Sample Evaluation">Sample Evaluation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\tt  get(2,\, from \; 6) \\
\tt  get(2,\, Cons(6, fun \; () \rightarrow  from \; (6+1))) \\
\tt  6 :: get(1,\, from \; (6+1)) \\
\tt  6 :: get(1,\, Cons \; (7,\, fun \; () \rightarrow  from \; (7+1))) \\
\tt  6 :: 7 :: get(0,\, Cons \; (8,\, fun \; () \rightarrow  from \; (8+1))) \\
\tt  6 :: 7 :: [] \\
\tt  [6; 7]
\end {aligned}
]]></fr:tex>
                    <html:p>Here we ask for two elements of the infinite sequence.  In fact, three
elements are computed: 6, 7 and 8.  Our implementation is slightly too eager.
A more complicated <html:code>type</html:code> declaration could avoid this problem.
Another problem is that if one repeatedly examines some particular list
element using forcing, that element is repeatedly evaluated.  In a lazy
programming language, the result of the first evaluation would be stored for
later reference.  To get the same effect in OCaml requires the use of
<fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">references</fr:link>.</html:p>
                    <html:p>We should be grateful that the potentially infinite computation is kept
finite.  The tail of the original sequence even contains the unevaluated
expression 6+1.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sample-costs/</fr:uri>
                    <fr:display-uri>focs-sample-costs</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sample-costs/</fr:route>
                    <fr:title text="Sample costs in O notation">Sample costs in O notation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Recall that <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> computes <fr:tex display="inline"><![CDATA[x^n]]></fr:tex>
by repeated multiplication while <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> naively computes the sum
<fr:tex display="inline"><![CDATA[1+\cdots +n]]></fr:tex>.  Each obviously performs <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> arithmetic operations.  Because
they are not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail recursive</fr:link>, their use of space is also <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  The function
<fr:link href="/~avsm2/fcs/focs-summing-iter/" title="Iteratively summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/" display-uri="focs-summing-iter" type="local"><html:code>summing</html:code></fr:link> is a version of <html:code>nsum</html:code> with an accumulating argument;
its iterative behaviour lets it work in constant space.  <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> spares
us from having to specify the units used to measure space.</html:p>
                    <html:table>
  <html:tr><html:th>Function</html:th><html:th>Time</html:th><html:th>Space</html:th></html:tr>
  <html:tr><html:td>npower, nsum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>summing</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n(n+1)/2]]></fr:tex></html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>power</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>sillySum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[2^n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
</html:table>
                    <html:p>Even ignoring constant factors, the units chosen can influence the result.
Multiplication may be regarded as a single unit of cost.  However, the cost of
multiplying two <fr:tex display="inline"><![CDATA[n]]></fr:tex>-digit numbers for large <fr:tex display="inline"><![CDATA[n]]></fr:tex> is itself an important
question, especially now that public-key cryptography uses numbers hundreds of
digits long.</html:p>
                    <html:p>Few things can <html:em>really</html:em> be done in constant time or stored in constant
space.  Merely to store the number <fr:tex display="inline"><![CDATA[n]]></fr:tex> requires <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> bits.  If a
program cost is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>, then we have probably assumed that certain operations
it performs are also <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>—typically because we expect never to exceed the
capacity of the standard hardware arithmetic.</html:p>
                    <html:p>With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>, the precise number of operations depends upon <fr:tex display="inline"><![CDATA[n]]></fr:tex> in a
complicated way, depending on how many odd numbers arise, so it is convenient
that we can just write <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  An accumulating argument could reduce its
space cost to <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/</fr:uri>
                    <fr:display-uri>focs-sillysum</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sillysum/</fr:route>
                    <fr:title text="Silly Summing the First n Integers">Silly Summing the First n Integers</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec sillySum n =
    if n = 0 then
      0
    else
      n + (sillySum (n - 1) + sillySum (n - 1)) / 2
val sillySum : int -> int = <fun>]]></html:pre>
                    <html:p>The function calls itself <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> times!  Bigger inputs mean higher costs—but
what’s the growth rate?</html:p>
                    <html:p>Now let us consider how to estimate various costs associated with a program.
<html:em><fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local">Asymptotic complexity</fr:link></html:em> refers to how costs—usually time or space—grow with
increasing inputs. Space complexity can never exceed time complexity, for it
takes time to do anything with the space.  Time complexity often greatly
exceeds space complexity.</html:p>
                    <html:p>The function <html:code>sillySum</html:code> calls itself twice in each <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> step.  This
function is contrived, but many mathematical formulas refer to a particular
quantity more than once.  In OCaml, we can create a local binding to a computed
value using the <html:em>local declaration</html:em> syntax. In the following expression, <html:code>y</html:code> is
computed once and used twice:</html:p>
                    <html:pre><![CDATA[# let x = 2.0 in
  let y = Float.pow x 20.0 in
  y *. (x /. y)
- : float = 2.]]></html:pre>
                    <html:p>You can read <html:code>let x = e1 in e2</html:code> as assigning (or "binding") the name <html:code>x</html:code> with
the value of <html:code>e1</html:code> into <html:code>e2</html:code>. Any use of <html:code>x</html:code> within <html:code>e2</html:code> will have the value of <html:code>e1</html:code>,
and <html:code>x</html:code> will only be visible in subexpressions into which it has been bound.</html:p>
                    <html:p>Why do we need let bindings? Fast hardware does not make good algorithms unnecessary.
On the contrary, faster hardware magnifies the superiority of better algorithms.
Typically, we want to handle the largest inputs possible.  If we double our processing power,
what do we gain?  How much can we increase <fr:tex display="inline"><![CDATA[n]]></fr:tex>, the input to our function?</html:p>
                    <html:p>With <html:code>sillySum</html:code>, we can only go from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>.  We are limited to this
modest increase because the function’s running time is proportional to <fr:tex display="inline"><![CDATA[2^n]]></fr:tex>.
With the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> defined in the previous section, we can go from <fr:tex display="inline"><![CDATA[n]]></fr:tex>
to <fr:tex display="inline"><![CDATA[2n]]></fr:tex>: we can handle problems twice as big.  With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> we can do much
better still, going from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
                    <html:p>The following table (excerpted from <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">a 50-year-old book</fr:link>!)
illustrates the effect of various time complexities.  The left-hand column (dubbed "complexity")
is defind as how many milliseconds are required to process an input of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
The other entries show the maximum size of <fr:tex display="inline"><![CDATA[n]]></fr:tex> that can be processed in the given time (one
second, minute or hour).</html:p>
                    <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>gain</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td><fr:tex display="inline"><![CDATA[\times  60]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td><fr:tex display="inline"><![CDATA[\times  41]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td><fr:tex display="inline"><![CDATA[\times  8]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td><fr:tex display="inline"><![CDATA[\times  4]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td><fr:tex display="inline"><![CDATA[+6]]></fr:tex></html:td></html:tr>
</html:table>
                    <html:p>The table illustrates how large an input can be processed as a function
of time.  As we increase the computer time per input from one second to one
minute and then to one hour, the size of the input increases accordingly.</html:p>
                    <html:p>The top two rows (complexities <fr:tex display="inline"><![CDATA[n]]></fr:tex> and <fr:tex display="inline"><![CDATA[n \lg  n]]></fr:tex>) increase rapidly: for <fr:tex display="inline"><![CDATA[n]]></fr:tex>, by
a factor of 60 per column.  The bottom two start out close together, but <fr:tex display="inline"><![CDATA[n^3]]></fr:tex> (which
grows by a factor of 3.9) pulls well away from <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> (whose growth is only
additive).  If an algorithm’s complexity is exponential then it can never
handle large inputs, even if it is given huge resources.  On the other hand,
suppose the complexity has the form <fr:tex display="inline"><![CDATA[n^c]]></fr:tex>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is a constant.  (We say
the complexity is <html:em>polynomial</html:em>.)  Doubling the argument then increases the
cost by a constant factor.  That is much better, though if <fr:tex display="inline"><![CDATA[c>3]]></fr:tex> the algorithm
may not be considered practical.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recurrences/</fr:uri>
                    <fr:display-uri>focs-recurrences</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-recurrences/</fr:route>
                    <fr:title text="Some Simple Recurrence Relations">Some Simple Recurrence Relations</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider a function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> that has a cost we want to bound using <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link>.
A typical <html:em>base case</html:em> is <fr:tex display="inline"><![CDATA[T(1)=1]]></fr:tex>.  Some <html:em>recurrences</html:em> are:</html:p>
                    <html:table>
  <html:tr><html:th>Equation</html:th><html:th>Complexity</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex></html:td></html:tr>
</html:table>
                    <html:p>To analyse a function, inspect its OCaml declaration.  Recurrence equations for
the cost function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> can usually be read off.  Since we ignore constant
factors, we can give the base case a cost of one unit.  Constant work done in
the recursive step can also be given unit cost; since we only need an upper
bound, this unit represents the larger of the two actual costs.  We could use
other constants if it simplifies the algebra.</html:p>
                    <html:p>For example, recall our function <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec nsum n =
    if n = 0 then
      0
    else
      n + nsum (n - 1)
val nsum : int -> int = <fun>]]></html:pre>
                    <html:p>Given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, it performs a constant amount of work (an addition and
subtraction) and calls itself recursively with argument <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  We get the
recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex>.  The closed form is
clearly <fr:tex display="inline"><![CDATA[T(n)=n+1]]></fr:tex>, as we can easily verify by substitution.  The cost is
<html:em>linear</html:em>.</html:p>
                    <html:p>This function, given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, calls <html:code>nsum</html:code>, performing <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> work.
Again ignoring constant factors, we can say that this call takes exactly <fr:tex display="inline"><![CDATA[n]]></fr:tex>
units.</html:p>
                    <html:pre><![CDATA[# let rec nsumsum n =
    if n = 0 then
      0
    else
      nsum n + nsumsum (n - 1)
val nsumsum : int -> int = <fun>]]></html:pre>
                    <html:p>We get the recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>.  It is easy to
see that <fr:tex display="inline"><![CDATA[T(n)=(n-1)+\cdots +1=n(n-1)/2=O(n^2)]]></fr:tex>.  The cost is
<html:em>quadratic</html:em>.</html:p>
                    <html:p>The function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> divides its input <fr:tex display="inline"><![CDATA[n]]></fr:tex> into two, with
the recurrence equation <fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex>.  Clearly <fr:tex display="inline"><![CDATA[T(2^n)=n+1]]></fr:tex>, so
<fr:tex display="inline"><![CDATA[T(n)=O(\log  n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/</fr:uri>
                    <fr:display-uri>focs-nsum</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nsum/</fr:route>
                    <fr:title text="Summing the first n integers">Summing the first n integers</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nsum n =
    if n = 0 then
      0
    else
      n + nsum (n - 1)
val nsum : int -> int = <fun>]]></html:pre>
                    <html:p>The function call <html:code>nsum n</html:code> computes the sum <html:code>1 +</html:code> … <html:code>+ nz</html:code> rather naively, hence the
initial <html:code>n</html:code> in its name:</html:p>
                    <fr:tex display="block"><![CDATA[\begin {aligned}
\text {nsum}\;3 \Rightarrow  &\; 3 + (\text {nsum}\;2) \\
               \Rightarrow  &\; 3 + (2 + (\text {nsum}\;1)) \\
               \Rightarrow  &\; 3 + (2 + (1 + (\text {nsum}\;0))) \\
               \Rightarrow  &\; 3 + (2 + (1 + 0))
\end {aligned}]]></fr:tex>
                    <html:p>The nesting of parentheses is not just an artifact of
our notation; it indicates a real problem.  The function gathers up a
collection of numbers, but none of the additions can be performed until <html:code>nsum
0</html:code> is reached.  Meanwhile, the computer must store the numbers in an internal
data structure, typically the <html:em>stack</html:em>.  For large <html:code>n</html:code>, say <html:code>nsum 10000</html:code>, the
computation might fail due to stack overflow.</html:p>
                    <html:p>We all know that the additions can be performed as we go along.  How do we
make the computer do that?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/</fr:uri>
                    <fr:display-uri>focs-def-tail-recursion</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-tail-recursion/</fr:route>
                    <fr:title text="Tail recursion">Tail recursion</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A recursive function whose computation does not nest is called <html:em>iterative</html:em>
or <html:em>tail-recursive</html:em>: the recursive calls do not nest, so the work is done
immediately rather than on the way back out. Many functions can be made
iterative by introducing an extra argument, which is often called an
<html:em>accumulator</html:em>.
Introduced in <fr:link href="/~avsm2/fcs/focs-summing-iter/" title="Iteratively summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/" display-uri="focs-summing-iter" type="local">Iteratively summing the first n integers</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/</fr:uri>
                    <fr:display-uri>focs-infinite-sequence</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-infinite-sequence/</fr:route>
                    <fr:title text="The Infinite Sequence: k, k+1, k+2, …">The Infinite Sequence: <fr:tex display="inline"><![CDATA[k]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+1]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+2]]></fr:tex>, …</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec from k = Cons (k, fun () -> from (k+1))
val from : int -> int seq = <fun>
# let it = from 1
val it : int seq = Cons (1, <fun>)
# let it = tail it
val it : int seq = Cons (2, <fun>)
# let it = tail it
val it : int seq = Cons (3, <fun>)]]></html:pre>
                    <html:p>Function <html:code>from</html:code> constructs the infinite sequence of integers starting
from <fr:tex display="inline"><![CDATA[k]]></fr:tex>.  Execution terminates because of the <html:code>fun</html:code> enclosing the
recursive call.  OCaml displays the tail of a sequence as <html:code>fun</html:code>, which
stands for some function value.  Each call to <html:code>tail</html:code> generates the next
sequence element.  We could do this forever.</html:p>
                    <html:p>This example is of little practical value because the cost of computing a
sequence element will be dominated by that of creating the dummy function.
<fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">Lazy lists</fr:link> tend to have high overheads.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/</fr:uri>
                    <fr:display-uri>focs-bst-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-update/</fr:route>
                    <fr:title text="Update">Update</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update k v = function
  | Lf -> Br ((k, v), Lf, Lf)
  | Br ((a, x), t1, t2) ->
      if k < a then
        Br ((a, x), update k v t1, t2)
      else if a < k then
        Br ((a, x), t1, update k v t2)
      else (* a = k *)
        Br ((a, v), t1, t2)
val update : 'a -> 'b -> ('a * 'b) tree -> ('a * 'b) tree = <fun>]]></html:pre>
                    <html:p>This is also <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> as it copies the path only, and <html:em>not whole subtrees!</html:em></html:p>
                    <html:p>If you are familiar with the usual update operation for this sort of tree, you
may wonder whether it can be implemented in OCaml, where there is no direct way to
replace part of a data structure by something else.</html:p>
                    <html:p>The update operation is a nice piece of functional programming.  It searches
in the same manner as <fr:link href="/~avsm2/fcs/focs-bst-lookup/" title="Lookup: Seeks Left or Right" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/" display-uri="focs-bst-lookup" type="local"><html:code>lookup</html:code></fr:link>, but the recursive calls reconstruct a
new tree around the result of the update.  One subtree is updated and the
other left unchanged.  The internal representation of trees ensures that
unchanged parts of the tree are not copied, but <html:em>shared</html:em>.
Therefore, update copies only the path from the root to the new
node.  Its time and space requirements, for a reasonably balanced tree, are
both <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.</html:p>
                    <html:p>The comparison between <fr:tex display="inline"><![CDATA[b]]></fr:tex> and <fr:tex display="inline"><![CDATA[a]]></fr:tex> allows three cases:</html:p>
                    <html:ul><html:li>smaller: update the left subtree; share the right</html:li>
<html:li>greater: update the right subtree; share the left</html:li>
<html:li>equal: update the label and share both subtrees</html:li></html:ul>
                    <html:p>Note: in the function definition, <html:code>(* a = b*)</html:code> is a comment.  Comments
in OCaml are enclosed in the brackets <html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-4/</fr:uri>
                    <fr:display-uri>focs-ex-2-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-2-4/</fr:route>
                    <fr:title text="Exercises › A tighter recurrence bound"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › A tighter recurrence bound</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Find an upper bound for the recurrence given by <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+1]]></fr:tex>.  You should be
able to find a tighter bound than <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-4/</fr:uri>
                    <fr:display-uri>focs-ex-4-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-4/</fr:route>
                    <fr:title text="Exercises › Assumptions in making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Assumptions in making change</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>What assumptions do the <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">‘making change’</fr:link> functions make about the variables <html:code>till</html:code> and <html:code>amt</html:code>?
Describe what could happen if these assumptions were violated.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-5/</fr:uri>
                    <fr:display-uri>focs-ex-4-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-5/</fr:route>
                    <fr:title text="Exercises › Counting ways of making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Counting ways of making change</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the number of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">ways of making change</fr:link> for <fr:tex display="inline"><![CDATA[n]]></fr:tex> (ignoring order) is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> if there are two
legal coin values. What if there are three, four, … coin values?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-3/</fr:uri>
                    <fr:display-uri>focs-ex-3-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-3/</fr:route>
                    <fr:title text="Exercises › Even-numbered elements"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Even-numbered elements</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to return the list consisting of the even-numbered elements of the list given as its
argument. For example, given <html:code>[a; b; c; d]</html:code> it should return <html:code>[b; d]</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-5/</fr:uri>
                    <fr:display-uri>focs-ex-1-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-5/</fr:route>
                    <fr:title text="Exercises › Floating-point error by repeated addition"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Floating-point error by repeated addition</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Because computer arithmetic is based on binary numbers, simple decimals such as 0.1 often cannot be
represented exactly. Write a function <html:code>mul</html:code> that performs the computation</html:p>
                    <fr:tex display="block"><![CDATA[\underbrace {x+x+\cdots +x}_{n}]]></fr:tex>
                    <html:p>where <fr:tex display="inline"><![CDATA[x]]></fr:tex> has type <html:code>float</html:code>. (It is essential to use repeated addition rather than multiplication!)</html:p>
                    <html:p>The value computed with <html:code>n = 10000</html:code> and <html:code>x = 0.1</html:code> may print as
<html:code>1000.0</html:code>, which looks exact. If that happens, then evaluate the
expression <html:code>mul 0.1 10000 -. 1000.0</html:code></html:p>
                    <html:p>An error of this type has been blamed for the failure of an American Patriot Missile battery to
intercept an incoming Iraqi missile during the <fr:link href="https://en.wikipedia.org/wiki/MIM-104_PatriotFailure_at_Dhahran" type="external">first Gulf War</fr:link>.
The missile hit an American Army barracks, killing 28.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-6/</fr:uri>
                    <fr:display-uri>focs-ex-1-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-6/</fr:route>
                    <fr:title text="Exercises › Golden ratio instability"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Golden ratio instability</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another example of the <fr:link href="/~avsm2/fcs/focs-floating-point/" title="Example 2: Floating Point Numbers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/" display-uri="focs-floating-point" type="local">inaccuracy of floating-point arithmetic</fr:link> takes the golden ratio
<fr:tex display="inline"><![CDATA[\phi \approx 1.618\ldots ]]></fr:tex> as its starting point:</html:p>
                    <fr:tex display="block"><![CDATA[\gamma _0 = \frac {1+\sqrt 5}{2} \quad \text {and}\quad \gamma _{n+1} = \frac {1}{\gamma _n-1}.]]></fr:tex>
                    <html:p>In theory, it is easy to prove that <fr:tex display="inline"><![CDATA[\gamma _n=\cdots  = \gamma _1 = \gamma _0]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>. Code this
computation in OCaml and report the value of <fr:tex display="inline"><![CDATA[\gamma _{50}]]></fr:tex>. <html:em>Hint:</html:em> in OCaml, <fr:tex display="inline"><![CDATA[\sqrt 5]]></fr:tex> is expressed
as <html:code>sqrt 5.0</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-4/</fr:uri>
                    <fr:display-uri>focs-ex-5-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-4/</fr:route>
                    <fr:title text="Exercises › Implementing bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing bubble sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement bubble sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-2/</fr:uri>
                    <fr:display-uri>focs-ex-5-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-2/</fr:route>
                    <fr:title text="Exercises › Implementing selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing selection sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement selection sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-1/</fr:uri>
                    <fr:display-uri>focs-ex-2-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-2-1/</fr:route>
                    <fr:title text="Exercises › Iterative power"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Iterative power</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version of the function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-2/</fr:uri>
                    <fr:display-uri>focs-ex-11-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-2/</fr:route>
                    <fr:title text="Exercises › Iterative power with while"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Iterative power with while</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a version of function <html:code>power</html:code> (<fr:link href="/~avsm2/fcs/focs-intro/" title="Introduction to Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" type="local">Lecture <fr:contextual-number uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" /></fr:link>) using <html:code>while</html:code> instead of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-3/</fr:uri>
                    <fr:display-uri>focs-ex-9-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-3/</fr:route>
                    <fr:title text="Exercises › Making change lazily"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Making change lazily</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">make change</fr:link> using <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, delivering the sequence of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">all possible ways of
making change</fr:link>. Using sequences allows us to compute solutions one at a time when there exists an
astronomical number. Represent lists of coins using ordinary lists. (<html:em>Hint</html:em>: to  benefit from
laziness you may need to pass around the sequence of alternative solutions as a function of type
<html:code>unit -&gt; (int list) seq</html:code>.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-5/</fr:uri>
                    <fr:display-uri>focs-ex-8-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-5/</fr:route>
                    <fr:title text="Exercises › Making change with map"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Making change with map</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Recall the making change function of <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">More on Lists</fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                    <html:p>Function <html:code>allc</html:code> applies the function ‘cons a <html:code>c</html:code>’ to every element of a list. Eliminate it by
declaring a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried</fr:link> cons function and applying <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-2/</fr:uri>
                    <fr:display-uri>focs-ex-4-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-2/</fr:route>
                    <fr:title text="Exercises › Partitioning integers by sign"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Partitioning integers by sign</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function that takes a list of integers and returns two lists, the first consisting of all
non-negative numbers found in the input and the second consisting of all the negative numbers.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-1/</fr:uri>
                    <fr:display-uri>focs-ex-3-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-1/</fr:route>
                    <fr:title text="Exercises › Summing a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Summing a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function</fr:link> to compute the sum of a list’s elements. Then code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version
and comment on the improvement in efficiency.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-2/</fr:uri>
                    <fr:display-uri>focs-ex-6-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-2/</fr:route>
                    <fr:title text="Exercises › Summing tree labels"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Summing tree labels</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write an OCaml function taking a binary tree labelled with integers and returning their sum.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-5/</fr:uri>
                    <fr:display-uri>focs-ex-3-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-5/</fr:route>
                    <fr:title text="Exercises › Tails of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Tails of a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function <html:code>tails</html:code> to return the list of the tails of its argument. For example, given
<html:code>[1; 2; 3]</html:code> it should return <html:code>[[1; 2; 3]; [2; 3]; [3]; []]</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-4/</fr:uri>
                    <fr:display-uri>focs-ex-1-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-4/</fr:route>
                    <fr:title text="Exercises › Type inference in power"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Type inference in power</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Functions <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> both return a <html:code>float</html:code>. The definition of <html:code>npower</html:code> returns the float
value <html:code>1.0</html:code> in its base case. The definition of <html:code>power</html:code> does not, so how does the OCaml type checker
know that <html:code>power</html:code> returns a <html:code>float</html:code>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-3/</fr:uri>
                    <fr:display-uri>focs-ex-6-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-3/</fr:route>
                    <fr:title text="Exercises › What ftree builds"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › What ftree builds</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Using the <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">definition of <html:code>'a tree</html:code></fr:link> from before:</html:p>
                    <html:pre><![CDATA[type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                    <html:p>Examine the following function declaration. What does <html:code>ftree (1, n)</html:code> accomplish?</html:p>
                    <html:pre><![CDATA[let rec ftree k n =
  if n = 0 then Lf
  else Br (k, ftree (2 * k) (n - 1), ftree (2 * k + 1) (n - 1))]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-complexity/</fr:uri>
                <fr:display-uri>focs-topic-complexity</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-complexity/</fr:route>
                <fr:title text="Complexity">Complexity</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-faster/</fr:uri>
                    <fr:display-uri>focs-change-faster</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-faster/</fr:route>
                    <fr:title text="All Ways of Making Change — Faster!">All Ways of Making Change — Faster!</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec change till amt chg chgs =
    match till, amt with
    | _       , 0   -> chg::chgs
    | []      , _   -> chgs
    | c::till , amt -> if amt < 0 then chgs
                       else change (c::till) (amt - c) (c::chg)
                                   (change till amt chg chgs)
val change : int list -> int -> int list -> int list list -> int list list =
  <fun>]]></html:pre>
                    <html:p>We’ve added <html:em>another</html:em> accumulating parameter!  Repeatedly improving simple code
is called <html:em>stepwise refinement</html:em>.</html:p>
                    <html:p>Two extra arguments eliminate many <html:code>::</html:code> and append operations from the previous
slide’s <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local"><html:code>change</html:code></fr:link> function.  The first, <html:code>chg</html:code>, accumulates the coins chosen so
far; one evaluation of <html:code>c::chg</html:code> replaces many evaluations of <html:code>allc</html:code>.  The
second, <html:code>chgs</html:code>, accumulates the list of solutions so far; it avoids the need
for <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link>.  This version runs several times faster than the previous one.</html:p>
                    <html:p>Making change is still extremely slow for an obvious reason: the number of
solutions grows rapidly in the amount being changed.  Using 50, 20, 10, 5,
2 and 1, there are 4366 ways of expressing 99.</html:p>
                    <html:p>Our three change functions illustrate a basic technique: program development
by stepwise refinement.  Begin by writing a very simple program and add
requirements individually.  Add efficiency refinements last of all.
Even if the simpler program cannot be included in the next version and has
to be discarded, one has learned about the task by writing it.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/</fr:uri>
                    <fr:display-uri>focs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-append/</fr:route>
                    <fr:title text="Append: List Concatenation">Append: List Concatenation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec append xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> x :: append xs ys
val append : 'a list -> 'a list -> 'a list = <fun>
# append [1; 2; 3] [4]
- : int list = [1; 2; 3; 4]
# let (@) = append
val ( @ ) : 'a list -> 'a list -> 'a list = <fun>
# [1; 2; 3] @ [4]
- : int list = [1; 2; 3; 4]]]></html:pre>
                    <html:p>Patterns can be as complicated as we like.  Here, the two patterns are
<html:code>[], ys</html:code> and <html:code>x::xs, ys</html:code>.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {append }[1; 2; 3] [4] \Rightarrow  &\; 1 :: \text {append }[2; 3]\;[4] \\
  \Rightarrow  &\; 1 :: (2 :: \text {append }[3]\;[4]) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: \text {append }[]\;[4])) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: [4])) \ [1; 2; 3; 4]
\end {aligned}
]]></fr:tex>
                    <html:p>Here is how append might be declared, also noting that we have defined <html:code>@</html:code> as
an infix operator that is a more convenient way to call <html:code>append</html:code> on two lists.
However, this function is also not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It scans its first
argument, sets up a string of <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code> operations</fr:link> (<html:code>::</html:code>) and finally does them.</html:p>
                    <html:p>It uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its first argument.
<html:em>Its costs are independent of its second argument.</html:em></html:p>
                    <html:p>An accumulating argument could make it iterative, but with considerable
complication.  The iterative version would still require <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time
because concatenation requires copying all the elements of the first list.
Therefore, we cannot hope for asymptotic gains; at best we can decrease the
constant factor involved in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>, but complicating the code is likely to
increase that factor.  Never add an accumulator merely out of habit.</html:p>
                    <html:p>Note append’s <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic type</fr:link>. It tells us that two lists can be joined if
their element types agree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-complexity-classes/</fr:uri>
                    <fr:display-uri>focs-complexity-classes</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-complexity-classes/</fr:route>
                    <fr:title text="Common Complexity Classes">Common Complexity Classes</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is <html:em>constant</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> is <html:em>logarithmic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> is <html:em>linear</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> is <html:em>quasi-linear</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> is <html:em>quadratic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(n^3)]]></fr:tex> is <html:em>cubic</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(a^n)]]></fr:tex> is <html:em>exponential</html:em> (for fixed <fr:tex display="inline"><![CDATA[a]]></fr:tex>)</html:li></html:ul>
                    <html:p>Logarithms grow very slowly, so <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> complexity is excellent.  Because
<fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> ignores constant factors, the base of the logarithm is
irrelevant!</html:p>
                    <html:p>Under linear we might mention <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>, which occasionally is called
<html:em>quasilinear</html:em> and which scales up well for large <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>An example of quadratic complexity is matrix addition: forming the sum of two
<fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> matrices obviously takes <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> additions.  Matrix
multiplication is of cubic complexity, which limits the size of matrices that
we can multiply in reasonable time.  An <fr:tex display="inline"><![CDATA[O(n^{2.81})]]></fr:tex> algorithm exists, but it
is too complicated to be of much use, even though it is theoretically better.</html:p>
                    <html:p>An exponential growth rate such as <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> restricts us to small values of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
Already with <fr:tex display="inline"><![CDATA[n=20]]></fr:tex> the cost exceeds one million.  However, the worst case
might not arise in normal practice.  OCaml type-checking is exponential in the
worst case, but not for ordinary programs.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/</fr:uri>
                    <fr:display-uri>focs-o-notation</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-o-notation/</fr:route>
                    <fr:title text="Comparing Algorithms: O Notation">Comparing Algorithms: O Notation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Formally, define <fr:tex display="inline"><![CDATA[f(n) = O(g(n))]]></fr:tex> provided <fr:tex display="inline"><![CDATA[|f(n)| \leq  c|g(n)|]]></fr:tex> as <fr:tex display="inline"><![CDATA[n\to \infty ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[|f(n)|]]></fr:tex> is bounded for some constant <fr:tex display="inline"><![CDATA[c]]></fr:tex> and all <html:em>sufficiently large</html:em> <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:li>
  <html:li>Intuitively, look at the <html:em>most significant</html:em> term.</html:li>
  <html:li>Ignore <html:em>constant factors</html:em> as they seldom dominate and are often transitory</html:li></html:ul>
                    <html:p>For example: consider <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[3n^2+34n+433]]></fr:tex>.</html:p>
                    <html:p>The cost of a program is usually a complicated formula.  Often we should
consider only the most significant term.  If the cost is <fr:tex display="inline"><![CDATA[n^2 + 99n + 900]]></fr:tex>
for an input of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>, then the <fr:tex display="inline"><![CDATA[n^2]]></fr:tex> term will eventually dominate,
even though <fr:tex display="inline"><![CDATA[99n]]></fr:tex> is bigger for <fr:tex display="inline"><![CDATA[n<99]]></fr:tex>.
The constant term <fr:tex display="inline"><![CDATA[900]]></fr:tex> may look big, but it is soon dominated by <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
                    <html:p>Constant factors in costs can be ignored unless they are large.  For one thing,
they seldom make a difference: <fr:tex display="inline"><![CDATA[100n^2]]></fr:tex> will be better than <fr:tex display="inline"><![CDATA[n^3]]></fr:tex> in the long
run: or <html:em>asymptotically</html:em> to use the jargon.  Moreover, constant factors are
seldom stable.  They depend upon details such as which hardware, operating
system or programming language is being used.  By ignoring constant factors, we
can make comparisons between algorithms that remain valid in a broad range of
circumstances.</html:p>
                    <html:p>The “Big O” notation is commonly used to describe efficiency—to be precise,
<html:em>asymptotic complexity</html:em>.  It concerns the limit of a function as its
argument tends to infinity.  It is an abstraction that meets the informal
criteria that we have just discussed.
In the definition, <html:em>sufficiently large</html:em> means there is some constant <fr:tex display="inline"><![CDATA[n_0]]></fr:tex>
such that <fr:tex display="inline"><![CDATA[|f(n)|\leq  c|g(n)|]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n]]></fr:tex> greater than <fr:tex display="inline"><![CDATA[n_0]]></fr:tex>.  The
role of <fr:tex display="inline"><![CDATA[n_0]]></fr:tex> is to ignore finitely many exceptions to the bound, such as the
cases when <fr:tex display="inline"><![CDATA[99n]]></fr:tex> exceeds <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/</fr:uri>
                    <fr:display-uri>focs-functional-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues/</fr:route>
                    <fr:title text="Efficient Functional Queues: Code">Efficient Functional Queues: Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a queue =
  | Q of 'a list * 'a list
type 'a queue = Q of 'a list * 'a list
# let norm = function
  | Q ([], tls) -> Q (List.rev tls, [])
  | q -> q
val norm : 'a queue -> 'a queue = <fun>
# let qnull = function
  | Q ([], []) -> true
  | _ -> false
val qnull : 'a queue -> bool = <fun>
# let enq (Q (hds, tls)) x = norm (Q (hds, x::tls))
val enq : 'a queue -> 'a -> 'a queue = <fun>
# exception Empty
exception Empty
# let deq = function
  | Q (x::hds, tls) -> norm (Q (hds, tls))
  | _ -> raise Empty
val deq : 'a queue -> 'a queue = <fun>
# let qempty = Q ([], [])
val qempty : 'a queue = Q ([], [])
# let qhd = function
  | Q (x::_, _) -> x
  | _ -> raise Empty
val qhd : 'a queue -> 'a = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> of queues prevents confusion with other pairs of lists.  The empty
queue has both parts empty.</html:p>
                    <html:p>The function <html:code>norm</html:code> puts a queue into normal form, ensuring that the front part
is never empty unless the entire queue is empty.  Functions <html:code>deq</html:code> and <html:code>enq</html:code>
call <html:code>norm</html:code> to normalise their result.</html:p>
                    <html:p>Because queues are in normal form, their head is certain to be in their
front part, so <html:code>qhd</html:code> looks there.</html:p>
                    <html:p>Let us analyse the cost of an execution comprising (in any possible order) <fr:tex display="inline"><![CDATA[n]]></fr:tex>
<html:code>enq</html:code> operations and <fr:tex display="inline"><![CDATA[n]]></fr:tex> <html:code>deq</html:code> operations, starting with an
empty queue.  Each <html:code>enq</html:code> operation will perform one cons, adding an
element to the rear part.  Since the final queue must be empty, each element
of the rear part gets transferred to the front part.  The corresponding
reversals perform one cons per element.  Thus, the total cost of the series of
queue operations is <fr:tex display="inline"><![CDATA[2n]]></fr:tex> cons operations, an average of 2 per operation.  The
amortized time is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
                    <html:p>There is a catch.  The conses need not be distributed evenly; reversing a long
list could take up to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> of them.  Unpredictable delays make the approach
unsuitable for <html:em>real-time programming</html:em> where deadlines must be met.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues-idea/</fr:uri>
                    <fr:display-uri>focs-functional-queues-idea</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues-idea/</fr:route>
                    <fr:title text="Efficient Functional Queues: Idea">Efficient Functional Queues: Idea</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Represent the queue <fr:tex display="inline"><![CDATA[x_1\; x_2\; \ldots \; x_m\; y_n\; \ldots \; y_1]]></fr:tex> by any <html:em>pair of lists</html:em>
    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \; [y_1,y_2,\ldots ,y_n])]]></fr:tex></html:li>
  <html:li>Add new items to the <html:em>rear list</html:em></html:li>
  <html:li>Remove items from <html:em>front list</html:em> and if empty move <html:em>rear</html:em> to <html:em>front</html:em></html:li>
  <html:li><html:em>Amortized</html:em> time per operation is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p>Queues require efficient access at both ends: at the front, for removal, and
at the back, for insertion.  Ideally, access should take constant time,
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.  It may appear that lists cannot provide such access.  If
<html:code>enq(q, x)</html:code> performs <html:code>q@[x]</html:code>, then this operation will be <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  We
could represent queues by reversed lists, implementing <html:code>enq(q, x)</html:code> by
<html:code>x::q</html:code>, but then the <html:code>deq</html:code> and <html:code>qhd</html:code> operations would be
<fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Linear time is intolerable: a series of <fr:tex display="inline"><![CDATA[n]]></fr:tex> queue operations
could then require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time.</html:p>
                    <html:p>The solution is to represent a queue by a pair of lists, where</html:p>
                    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \, [y_1,y_2,\ldots ,y_n])]]></fr:tex>
                    <html:p>represents the queue <fr:tex display="inline"><![CDATA[x_1 x_2 \ldots  x_m y_n \ldots  y_1]]></fr:tex>.</html:p>
                    <html:p>The front part of the queue is stored in order, and the rear part is stored in
reverse order.  The <html:code>enq</html:code> operation adds elements to the rear part
using cons, since this list is reversed; thus, <html:code>enq</html:code> takes constant
time.  The <html:code>deq</html:code> and <html:code>qhd</html:code> operations look at the front part,
which normally takes constant time, since this list is stored in order.  But
sometimes <html:code>deq</html:code> removes the last element from the front part; when this
happens, it reverses the rear part, which becomes the new front part.</html:p>
                    <html:p><html:em>Amortized</html:em> time refers to the cost per operation averaged over the
lifetime of any complete execution.  Even for the worst possible execution,
the average cost per operation turns out to be constant; see the analysis
below.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/</fr:uri>
                    <fr:display-uri>focs-length</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-length/</fr:route>
                    <fr:title text="Efficiently Computing the Length of a List">Efficiently Computing the Length of a List</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec addlen n = function
  | []    -> n
  | x::xs -> addlen (n + 1) xs
val addlen : int -> 'a list -> int = <fun>
# addlen 0 [5; 6; 7]
- : int = 3]]></html:pre>
                    <html:p>Recall that the use of <html:code>function</html:code> introduces an extra (unnamed) argument
that is <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matched</fr:link> in the subsequent clauses; in this case, to break
open the list.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {addlen }0 [a; b; c] \Rightarrow  &\;  \text {addlen }1\;[b; c] \\
  \Rightarrow   &\; \text {addlen }2\;[c] \\
  \Rightarrow   &\; \text {addlen }3\;[] \\
  \Rightarrow   &\; 3
\end {aligned}
]]></fr:tex>
                    <html:p>Function <html:code>addlen</html:code> is again <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.  Its type mentions the integer
accumulator.</html:p>
                    <html:p>Now we may declare an efficient length function.  It is simply a wrapper for
<html:code>addlen</html:code>, supplying zero as the initial value of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# let length xs = addlen 0 xs
val length : 'a list -> int = <fun>
# length [5; 6; 7; 8]
- : int = 4]]></html:pre>
                    <html:p>The recursive calls do not nest: this version is <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It takes <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
space.  Obviously its time requirement is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> because it takes at least <fr:tex display="inline"><![CDATA[n]]></fr:tex>
steps to find the length of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/</fr:uri>
                    <fr:display-uri>focs-power</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-power/</fr:route>
                    <fr:title text="Efficiently Raising a Number to a Power">Efficiently Raising a Number to a Power</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec power x n =
    if n = 1 then x
    else if even n then
      power (x *. x) (n / 2)
    else
      x *. power (x *. x) (n / 2)
val power : float -> int -> float = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Mathematical Justification</html:em>
                    </html:p>
                    <fr:tex display="block"><![CDATA[\begin {aligned}
           x^1 & = x \\
           x^{2n} & = (x^2)^n  \\
           x^{2n+1} & = x\times (x^2)^n.
\end {aligned}]]></fr:tex>
                    <html:p>For large <html:code>n</html:code>, computing powers using <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> is too slow to
be practical.  The equations above are much faster. Example:</html:p>
                    <fr:tex display="block"><![CDATA[ 2^{12} = 4^6 = 16^3 = 16\times  256^1 = 16\times  256 = 4096. ]]></fr:tex>
                    <html:p>Instead of <html:code>n</html:code> multiplications, we need at most <fr:tex display="inline"><![CDATA[2\lg  n]]></fr:tex> multiplications,
where <fr:tex display="inline"><![CDATA[\lg  n]]></fr:tex> is the logarithm of <fr:tex display="inline"><![CDATA[n]]></fr:tex> to the base <fr:tex display="inline"><![CDATA[2]]></fr:tex>.</html:p>
                    <html:p>We use the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>even</html:code></fr:link>, declared previously, to test whether the
exponent is even.  Integer division (<html:code>/</html:code>) truncates its result to an
integer: dividing <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex> by 2 yields <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>A recurrence is a useful computation rule only if it is bound to terminate.
If <fr:tex display="inline"><![CDATA[n>0]]></fr:tex> then <fr:tex display="inline"><![CDATA[n]]></fr:tex> is smaller than both <fr:tex display="inline"><![CDATA[2n]]></fr:tex> and <fr:tex display="inline"><![CDATA[2n+1]]></fr:tex>.  After enough
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive calls</fr:link>, the exponent will be reduced to <fr:tex display="inline"><![CDATA[1]]></fr:tex>.  The equations also hold
if <fr:tex display="inline"><![CDATA[n\leq 0]]></fr:tex>, but the corresponding computation runs forever.</html:p>
                    <html:p>Our reasoning assumes arithmetic to be <html:em>exact</html:em>. Fortunately, the calculation is
well-behaved using floating-point.</html:p>
                    <html:p>Computer numbers have a finite range, which if exceeded results in the
integer wrapping around.  You will understand this behaviour more as you
learn about computer architecture and how modern systems represent
numbers in memory.</html:p>
                    <html:p>If integers and floats must be combined in a calculation, OCaml provides functions
to convert between them:</html:p>
                    <html:pre><![CDATA[# int_of_float 3.14159
- : int = 3
# float_of_int 3
- : float = 3.]]></html:pre>
                    <html:p>OCaml’s libraries are organised using “modules”, so we may use compound
identifiers such as <html:code>Float.of_int</html:code> to refer to library functions. There
are many thousands of library functions available in the OCaml ecosystem,
including text-processing and operating systems functions in addition to the
usual numerical ones.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/</fr:uri>
                    <fr:display-uri>focs-tree-traversal-efficient</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal-efficient/</fr:route>
                    <fr:title text="Efficiently Traversing Trees">Efficiently Traversing Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Unfortunately, the functions shown on the previous slide are quadratic in the
worst case: the appends in the recursive calls are inefficient.  To correct
that problem, we (as usual) add an accumulating argument.  Observe how
each function constructs its result list and compare with how appends were
eliminated from <html:code>quicksort</html:code> in the <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">Sorting lecture</fr:link>.</html:p>
                    <html:pre><![CDATA[# let rec preord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      v :: preord (t1, preord (t2, vs))
val preord : 'a tree * 'a list -> 'a list = <fun>
# let rec inord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      inord (t1, v::inord (t2, vs))
val inord : 'a tree * 'a list -> 'a list = <fun>
# let rec postord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      postord (t1, postord (t2, v::vs))
val postord : 'a tree * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>One can prove equations relating each of these functions to its counterpart on
the previous section.  For example:</html:p>
                    <fr:tex display="block"><![CDATA[\texttt {inord}(t, vs) = \texttt {inorder}(t) @ vs]]></fr:tex>
                    <html:p>These three types of tree traversal are related in that all are depth-first.
They each traverse the left subtree in full before traversing the right
subtree.  Breadth-first search (from the <fr:link href="/~avsm2/fcs/focs-queues/" title="Queues and Search Strategies" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queues/" display-uri="focs-queues" type="local">Queues lecture</fr:link>) is another
possibility.  That involves going through the levels of a tree one at a time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/</fr:uri>
                    <fr:display-uri>focs-functional-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-arrays/</fr:route>
                    <fr:title text="Functional Arrays as Binary Trees">Functional Arrays as Binary Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The path to element <fr:tex display="inline"><![CDATA[i]]></fr:tex> follows the <html:em>binary code</html:em> for <fr:tex display="inline"><![CDATA[i]]></fr:tex> (its “subscript”).</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifetc2v73r7qxnzo6bthiblab2tezbaqvmovq7e4q6vgdl5ewr3wi.svg" />
                    </html:figure>
                    <html:p>This simple representation (credited to W. Braun) ensures that the tree is
balanced.  Complexity of access is always <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>, which is optimal.  For
actual running time, access to conventional arrays is much faster: it requires
only a few hardware instructions.  Array access is often taken to be <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>,
which (as always) presumes that hardware limits are never exceeded.</html:p>
                    <html:p>The lower bound for array subscripts (or “indices”) is one.  The upper bound starts at zero
(which signifies the empty array) and can grow without limit.  Inspection of
the diagram above should make it clear that these trees are always balanced:
the left subtree can have at most one node more than the right subtree,
recursively all the way down.  (This assumes that the array is defined for
subscripts <fr:tex display="inline"><![CDATA[1\ldots  n]]></fr:tex> with no gaps; an array defined only for odd numbers, for
example, would obviously be unbalanced.)</html:p>
                    <html:p>The numbers in the diagram above are not the labels of branch nodes, but
indicate the positions of array elements. For example, the label corresponding
to <fr:tex display="inline"><![CDATA[A[2]]]></fr:tex> is at the position shown. The nodes of a functional array are
labelled with the data we want to store, not with these integers.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-bounds/</fr:uri>
                    <fr:display-uri>focs-sorting-bounds</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sorting-bounds/</fr:route>
                    <fr:title text="How Fast Can We Sort?">How Fast Can We Sort?</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>typically count <html:em>comparisons</html:em> <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex></html:li>
  <html:li>there are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements</html:li>
  <html:li>each comparison eliminates <html:em>half</html:em> of the permutations <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex></html:li>
  <html:li>therefore <fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex></html:li></html:ul>
                    <html:p>The usual measure of efficiency for sorting algorithms is the number of
comparison operations required.  <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link> requires only <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>
comparisons to sort an input of <fr:tex display="inline"><![CDATA[n]]></fr:tex> items.  It is straightforward to prove
that this complexity is the best possible.  There
are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements and each comparison distinguishes two
permutations.  The lower bound on the number of comparisons, <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex>, is
obtained by solving <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex>; therefore
<fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex>.</html:p>
                    <html:p>In order to compare the sorting algorithms, we use the <fr:link href="http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf" type="external">following source</fr:link> of
pseudo-random numbers. Never mind how this works: generating
statistically good random numbers is hard.  Much effort has gone into those few
lines of code.</html:p>
                    <html:pre><![CDATA[# let nextrandom seed =
    let a = 16807.0 in
    let m = 2147483647.0 in
    let t = a *. seed in
    t -. m *. (floor (t /. m))
val nextrandom : float -> float = <fun>
# let rec randlist (seed, seeds) = function
    | 0 -> (seed, seeds)
    | n -> randlist (nextrandom seed, seed::seeds) (n-1)
val randlist : float * float list -> int -> float * float list = <fun>]]></html:pre>
                    <html:p>We can now bind the identifier <html:code>rs</html:code> to a list of 10,000 random numbers.</html:p>
                    <html:pre><![CDATA[# let seed, rs = randlist (1.0, []) 10000
val seed : float = 1043618065.
val rs : float list =
  [1484786315.; 925166085.; 1614852353.; 721631166.; 173942219.; 1229443779.;
   789328014.; 570809709.; 1760109362.; 270600523.; 2108528931.; 16480421.;
   519782231.; 162430624.; 372212905.; 1954184989.; 898872741.; 1651521688.;
   1114791388.; 1325968501.; 1469981427.; 465437343.; 1732504088.;
   280054095.; 1924919450.; 1244369648.; 1524535715.; 706293012.;
   1372325856.; 1302473561.; 941382430.; 2137445578.; 1937168414.;
   1852570660.; 495231255.; 1092873378.; 140232191.; 328129841.; 632752255.;
   227857208.; 1616471915.; 719842438.; 1402481130.; 745001020.; 791471334.;
   2131048000.; 312659966.; 1389551813.; 443838892.; 854190041.; 741774068.;
   267473377.; 1372555293.; 1539748349.; 697860888.; 1261546017.; 734770781.;
   1512111397.; 813238415.; 1034499961.; 602256496.; 462191385.; 250718457.;
   246489360.; 295426232.; 468306241.; 877829533.; 1130589227.; 1914364883.;
   1479854970.; 878528585.; 1268712064.; 115837978.; 1803525169.; 689954646.;
   1174020926.; 651968560.; 391152461.; 1776325865.; 2015344107.; 246977673.;
   1381242649.; 1115030853.; 190703911.; 316761032.; 464218769.; 1537522160.;
   1958981931.; 390463588.; 224009597.; 235243732.; 620352731.; 1374109567.;
   832140633.; 675075162.; 1296171190.; 2009054653.; 1534419747.; 145880482.;
   1649432515.; 403989126.; 1112417244.; 1290575192.; 896661113.; 218545469.;
   1002393512.; 2131316096.; 551979127.; 932010335.; 665881436.; 1975412808.;
   639877791.; 1781707137.; 894518191.; 568004958.; 1331430214.; 629489848.;
   183264178.; 162027282.; 464592882.; 93302056.; 1178713033.; 1401486247.;
   1846150129.; 1646978216.; 1104441491.; 111995009.; 66193165.; 2038880392.;
   79340676.; 871801051.; 967550305.; 2067810758.; 1600354198.; 1746626663.;
   1516388116.; 1308870791.; 173082747.; 189881227.; 478010722.; 739707315.;
   255334803.; 164203714.; 1893097038.; 1587694259.; 292950569.; 918323194.;
   41453146.; 1217297445.; 256768724.; 586494122.; 586258194.; 660494391.;
   507554325.; 699716071.; 672895139.; 76065072.; 1594869218.; 1439459639.;
   641123634.; 1650611940.; 177447368.; 301427463.; 525804524.; 553672425.;
   926899509.; 794676486.; 690277940.; 2115070333.; 1062048650.; 1653192448.;
   1808855340.; 126475289.; 1028198214.; 1739565096.; 1515748830.;
   427491435.; 319330584.; 666483848.; 854842154.; 1853528448.; 1975611245.;
   1905343266.; 1229802342.; 1416055428.; 2091603253.; 1068308139.;
   198239748.; 982076370.; 1094563396.; 44402415.; 889814989.; 290736902.;
   417580014.; 1935788352.; 595665917.; 367638848.; 894945148.; 1868608068.;
   317883051.; 941451621.; 1595942893.; 789094274.; 1150772108.; 422742112.;
   1444245279.; 1273601104.; 256005435.; 1742330161.; 1514599036.;
   956344512.; 2113041793.; 293237373.; 1386995194.; 1509339194.; 891946522.;
   1020832915.; 592544922.; 1746311153.; 1471539715.; 143832370.;
   2041568248.; 1039556199.; 1608726047.; 1205124472.; 2123533995.;
   1560620058.; 1837598795.; 1028172251.; 98318742.; 1405510706.;
   1047695837.; 59221314.; 1822176683.; 1096018886.; 1528104537.;
   1270922857.; 812074106.; 291115596.; 795788616.; 638657646.; 2034314619.;
   1527649272.; 156357479.; 1010056202.; 1139413443.; 1110927723.;
   1216083346.; 846825145.; 2100385733.; 315213605.; 1629637749.;
   1139833627.; 895118866.; 296359237.; 1361440746.; 1188627020.;
   1964199872.; 166733080.; 54185744.; 575493576.; 1810324496.; 1765549585.;
   53514233.; 747348448.; 61758907.; 1710119765.; 188311628.; 8827553.;
   67975851.; 1808633248.; 1290488843.; 1264775607.; 1711469075.;
   1537468597.; 706677101.; 518290019.; 190285086.; 157683412.; 985907152.;
   1571668636.; 632570698.; 791081325.; 1773794197.; 1787141077.;
   1727982894.; 794213057.; 633163306.; 682601940.; 1573439414.; 1041956036.;
   1169697582.; 758914445.; 2096291761.; 1502226099.; 1665995955.;
   948048264.; 1596326605.; 1816773893.; ...]]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/</fr:uri>
                    <fr:display-uri>focs-iterative-deepening</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-iterative-deepening/</fr:route>
                    <fr:title text="Iterative deepening: Another Exhaustive Search">Iterative deepening: Another Exhaustive Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Breadth-first search examines <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> nodes:
    <fr:tex display="block"><![CDATA[1 + b + \cdots  + b^d = {b^{d+1}-1 \over  b-1}
  \qquad  \begin {array}[c]{rl}
            b & {} = \hbox {branching factor}\\
            d & {} = \hbox {depth}
          \end {array}]]></fr:tex></html:li>
  <html:li>Recompute nodes at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> instead of storing them</html:li>
  <html:li>Time factor is <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>; complexity is still <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex></html:li>
  <html:li>Space required at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> drops from <fr:tex display="inline"><![CDATA[b^d]]></fr:tex> to <fr:tex display="inline"><![CDATA[d]]></fr:tex></html:li></html:ul>
                    <html:p>Breadth-first search is not practical for infinite trees: it uses too much
space. Large parts of the tree have to be stored.
Consider the slightly more general problem of searching trees whose
branching factor is <fr:tex display="inline"><![CDATA[b]]></fr:tex> (for binary trees, <fr:tex display="inline"><![CDATA[b=2]]></fr:tex>).  Then breadth-first search
to depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> examines <fr:tex display="inline"><![CDATA[(b^{d+1}-1)/(b-1)]]></fr:tex> nodes, which is <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>, ignoring
the constant factor of <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex>.  Since all nodes that are examined are also
stored, the space and time requirements are both <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.</html:p>
                    <html:p><html:em>Depth-first iterative deepening</html:em> combines the space efficiency of
depth-first with the “nearest-first” property of breadth-first search.  It
performs repeated depth-first searches with increasing depth bounds, each time
discarding the result of the previous search.  Thus it searches to depth 1,
then to depth 2, and so on until it finds a solution.  We can afford to
discard previous results because the number of nodes is growing exponentially.
There are <fr:tex display="inline"><![CDATA[b^{d+1}]]></fr:tex> nodes at level <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>; if <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex>, this number actually
exceeds the total number of nodes of all previous levels put together, namely
<fr:tex display="inline"><![CDATA[(b^{d+1}-1) / (b-1)]]></fr:tex>.</html:p>
                    <html:p><fr:link href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288" type="external">Korf shows</fr:link> that the time needed for iterative deepening to reach
depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> is only <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> times that for breadth-first search, if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>.
This is a constant factor; both algorithms have the same time complexity,
<fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.  In typical applications where <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex> the extra factor of
<fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> is quite tolerable.  The reduction in the space requirement is
exponential, from <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> for breadth-first to <fr:tex display="inline"><![CDATA[O(d)]]></fr:tex> for iterative
deepening. Of course, this assumes that the tree itself is not stored in memory.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/</fr:uri>
                    <fr:display-uri>focs-linear-search</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-linear-search/</fr:route>
                    <fr:title text="Linear Search">Linear Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>find <fr:tex display="inline"><![CDATA[x]]></fr:tex> in list <fr:tex display="inline"><![CDATA[[x_1,\ldots ,x_n]]]></fr:tex> by comparing with each element</html:li>
  <html:li>obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time</html:li>
  <html:li>simple &amp; general</html:li>
  <html:li>ordered searching needs only <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:li>
  <html:li>indexed lookup needs only <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p><html:em>Linear search</html:em> is the obvious way to find a desired item in a
collection: simply look through all the items, one at a time.  If <fr:tex display="inline"><![CDATA[x]]></fr:tex> is in
the list, then it will be found in <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> steps on average, and even the worst
case is obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                    <html:p>Large collections of data are usually ordered or indexed so that items can be
found in <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> time, which is exponentially better than <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Even
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is achievable (using a hash table), though subject to the usual
proviso that machine limits are not exceeded.</html:p>
                    <html:p>Efficient indexing methods are of prime importance: consider Web
search engines.  Nevertheless, linear search is often used to search small
collections because it is so simple and general, and it is the starting point
for better algorithms.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/</fr:uri>
                    <fr:display-uri>focs-def-o-notation</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-o-notation/</fr:route>
                    <fr:title text="O notation">O notation</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Formally, <fr:tex display="inline"><![CDATA[f(n) = O(g(n))]]></fr:tex> provided <fr:tex display="inline"><![CDATA[|f(n)| \leq  c|g(n)|]]></fr:tex> as <fr:tex display="inline"><![CDATA[n\to \infty ]]></fr:tex>,
that is, for some constant <fr:tex display="inline"><![CDATA[c]]></fr:tex> and all <html:em>sufficiently large</html:em> <fr:tex display="inline"><![CDATA[n]]></fr:tex>. The “Big
O” notation is commonly used to describe efficiency—to be precise,
<html:em>asymptotic complexity</html:em>—by looking only at the most significant term and
ignoring constant factors.
Introduced in <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local">Comparing Algorithms: O Notation</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/</fr:uri>
                    <fr:display-uri>focs-quicksort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort/</fr:route>
                    <fr:title text="Quicksort: The Code">Quicksort: The Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quick = function
    | [] -> []
    | [x] -> [x]
    | a::bs ->
        let rec part l r = function
          | [] -> (quick l) @ (a :: quick r)
          | x::xs ->
              if (x <= a) then
                part (x::l) r xs
              else
                part l (x::r) xs
        in
        part [] [] bs
val quick : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Our OCaml quicksort copies the items.  It is still pretty fast, and it is much
easier to understand.  It takes roughly 0.74 seconds to sort our list of random
numbers.</html:p>
                    <html:p>The function declaration consists of three clauses.  The first handles the
empty list; the second handles singleton lists (those of the form <html:code>[x]</html:code>); the
third handles lists of two or more elements.  Often, lists of length up to five
or so are treated as special cases to boost speed.</html:p>
                    <html:p>The locally declared function <html:code>part</html:code> partitions the input using <html:code>a</html:code> as the
pivot.  The arguments <html:code>l</html:code> and <html:code>r</html:code> accumulate items for the left (<fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>) and
right (<fr:tex display="inline"><![CDATA[>a]]></fr:tex>) parts of the input, respectively.</html:p>
                    <html:p>It is not hard to prove that quicksort does <fr:tex display="inline"><![CDATA[n\log  n]]></fr:tex> comparisons, <html:em>in the average case</html:em>
(see <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">page 94 of Aho</fr:link>).  With random data, the pivot
usually has an average value that divides the input in two approximately equal
parts.  We have the recurrence <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>, which is
<fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.  In our example, it is about 235 times faster than <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insertion
sort</fr:link>.</html:p>
                    <html:p>In the worst case, quicksort's running time is quadratic!  An example is when
its input is almost sorted or reverse sorted.  Nearly all of the items end up
in one partition; work is not divided evenly.  We have the recurrence
<fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>, which is <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Randomising the input
makes the worst case highly unlikely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/</fr:uri>
                    <fr:display-uri>focs-rev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-rev/</fr:route>
                    <fr:title text="Reversing a List in O(n)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec rev_app xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> rev_app xs (x::ys)
val rev_app : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {rev\_app }[a; b; c]\;[] \Rightarrow  &\; \text {rev\_app }[b; c]\; [a] \\
  \Rightarrow  &\; \text {rev\_app }[c]\; [b; a] \\
  \Rightarrow  &\; \text {rev\_app }[]\; [c; b; a] \\
  \Rightarrow  &\; [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>Calling <html:code>rev_app xs ys</html:code> reverses the elements of <html:code>xs</html:code> and
prepends them to <html:code>ys</html:code>.  Now we may declare</html:p>
                    <html:pre><![CDATA[# let rev xs = rev_app xs []
val rev : 'a list -> 'a list = <fun>
# rev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <html:p>It is easy to see that this reverse function performs just <fr:tex display="inline"><![CDATA[n]]></fr:tex> conses, given
an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.  For both reverse functions, we could count the number of
conses precisely—not just up to a constant factor.  <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> is still
useful to describe the overall running time: the time taken by a cons
varies from one system to another.</html:p>
                    <html:p>The accumulator <fr:tex display="inline"><![CDATA[y]]></fr:tex> makes the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  But the gain in complexity
arises from the removal of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.  Replacing an expensive operation (append)
by a series of cheap operations (cons) is called <html:em>reduction in strength</html:em>
and is a common technique in computer science.  It originated when many
computers did not have a hardware multiply instruction; the series of products
<fr:tex display="inline"><![CDATA[i\times  r]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, <fr:tex display="inline"><![CDATA[\ldots , n]]></fr:tex> could more efficiently be computed by
repeated addition.  Reduction in strength can be done in various ways; we
shall see many instances of removing append.</html:p>
                    <html:p>Consing to an accumulator produces the result in reverse.  If
that forces the use of an extra list reversal then the iterative function
may be much slower than the recursive one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nrev/</fr:uri>
                    <fr:display-uri>focs-nrev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nrev/</fr:route>
                    <fr:title text="Reversing a List in O(n^2)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Let us consider one way to reverse a list.</html:p>
                    <html:pre><![CDATA[# let rec nrev = function
  | [] -> []
  | x::xs -> (nrev xs) @ [x]
val nrev : 'a list -> 'a list = <fun>
# nrev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nrev }[a; b; c] \Rightarrow  &\; \text {nrev }[b; c]\;@\;[a] \\
  \Rightarrow  &\;  (\text {nrev }[c]\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  ((\text {nrev }[]\;@\;[c])\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  (([]\;@\;[c])\;@\;[b])\;@\;[a] \ \ldots  \ [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>This reverse function is grossly inefficient due to poor usage of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>, which
copies its first argument.  If <html:code>nrev</html:code> is given a list of length <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>, then
append makes <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> conses to copy the reversed tail.  Constructing the list
<html:code>[x]</html:code> calls <html:code>cons</html:code> again, for a total of <fr:tex display="inline"><![CDATA[n]]></fr:tex> calls.  Reversing the tail
requires <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> more conses, and so forth.  The total number of conses is:</html:p>
                    <fr:tex display="block"><![CDATA[ 0 + 1 + 2 + \cdots  + n = {n(n+1)/2} ]]></fr:tex>
                    <html:p>The time complexity is therefore <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Space complexity is only <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>
because the copies don’t all exist at the same time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sample-costs/</fr:uri>
                    <fr:display-uri>focs-sample-costs</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sample-costs/</fr:route>
                    <fr:title text="Sample costs in O notation">Sample costs in O notation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Recall that <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> computes <fr:tex display="inline"><![CDATA[x^n]]></fr:tex>
by repeated multiplication while <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> naively computes the sum
<fr:tex display="inline"><![CDATA[1+\cdots +n]]></fr:tex>.  Each obviously performs <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> arithmetic operations.  Because
they are not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail recursive</fr:link>, their use of space is also <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  The function
<fr:link href="/~avsm2/fcs/focs-summing-iter/" title="Iteratively summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-summing-iter/" display-uri="focs-summing-iter" type="local"><html:code>summing</html:code></fr:link> is a version of <html:code>nsum</html:code> with an accumulating argument;
its iterative behaviour lets it work in constant space.  <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> spares
us from having to specify the units used to measure space.</html:p>
                    <html:table>
  <html:tr><html:th>Function</html:th><html:th>Time</html:th><html:th>Space</html:th></html:tr>
  <html:tr><html:td>npower, nsum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>summing</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n(n+1)/2]]></fr:tex></html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[1]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>power</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[\log ~n]]></fr:tex>)</html:td></html:tr>
  <html:tr><html:td>sillySum</html:td><html:td>O(<fr:tex display="inline"><![CDATA[2^n]]></fr:tex>)</html:td><html:td>O(<fr:tex display="inline"><![CDATA[n]]></fr:tex>)</html:td></html:tr>
</html:table>
                    <html:p>Even ignoring constant factors, the units chosen can influence the result.
Multiplication may be regarded as a single unit of cost.  However, the cost of
multiplying two <fr:tex display="inline"><![CDATA[n]]></fr:tex>-digit numbers for large <fr:tex display="inline"><![CDATA[n]]></fr:tex> is itself an important
question, especially now that public-key cryptography uses numbers hundreds of
digits long.</html:p>
                    <html:p>Few things can <html:em>really</html:em> be done in constant time or stored in constant
space.  Merely to store the number <fr:tex display="inline"><![CDATA[n]]></fr:tex> requires <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> bits.  If a
program cost is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>, then we have probably assumed that certain operations
it performs are also <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>—typically because we expect never to exceed the
capacity of the standard hardware arithmetic.</html:p>
                    <html:p>With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link>, the precise number of operations depends upon <fr:tex display="inline"><![CDATA[n]]></fr:tex> in a
complicated way, depending on how many odd numbers arise, so it is convenient
that we can just write <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  An accumulating argument could reduce its
space cost to <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/</fr:uri>
                    <fr:display-uri>focs-sillysum</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sillysum/</fr:route>
                    <fr:title text="Silly Summing the First n Integers">Silly Summing the First n Integers</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec sillySum n =
    if n = 0 then
      0
    else
      n + (sillySum (n - 1) + sillySum (n - 1)) / 2
val sillySum : int -> int = <fun>]]></html:pre>
                    <html:p>The function calls itself <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> times!  Bigger inputs mean higher costs—but
what’s the growth rate?</html:p>
                    <html:p>Now let us consider how to estimate various costs associated with a program.
<html:em><fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local">Asymptotic complexity</fr:link></html:em> refers to how costs—usually time or space—grow with
increasing inputs. Space complexity can never exceed time complexity, for it
takes time to do anything with the space.  Time complexity often greatly
exceeds space complexity.</html:p>
                    <html:p>The function <html:code>sillySum</html:code> calls itself twice in each <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> step.  This
function is contrived, but many mathematical formulas refer to a particular
quantity more than once.  In OCaml, we can create a local binding to a computed
value using the <html:em>local declaration</html:em> syntax. In the following expression, <html:code>y</html:code> is
computed once and used twice:</html:p>
                    <html:pre><![CDATA[# let x = 2.0 in
  let y = Float.pow x 20.0 in
  y *. (x /. y)
- : float = 2.]]></html:pre>
                    <html:p>You can read <html:code>let x = e1 in e2</html:code> as assigning (or "binding") the name <html:code>x</html:code> with
the value of <html:code>e1</html:code> into <html:code>e2</html:code>. Any use of <html:code>x</html:code> within <html:code>e2</html:code> will have the value of <html:code>e1</html:code>,
and <html:code>x</html:code> will only be visible in subexpressions into which it has been bound.</html:p>
                    <html:p>Why do we need let bindings? Fast hardware does not make good algorithms unnecessary.
On the contrary, faster hardware magnifies the superiority of better algorithms.
Typically, we want to handle the largest inputs possible.  If we double our processing power,
what do we gain?  How much can we increase <fr:tex display="inline"><![CDATA[n]]></fr:tex>, the input to our function?</html:p>
                    <html:p>With <html:code>sillySum</html:code>, we can only go from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>.  We are limited to this
modest increase because the function’s running time is proportional to <fr:tex display="inline"><![CDATA[2^n]]></fr:tex>.
With the function <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> defined in the previous section, we can go from <fr:tex display="inline"><![CDATA[n]]></fr:tex>
to <fr:tex display="inline"><![CDATA[2n]]></fr:tex>: we can handle problems twice as big.  With <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> we can do much
better still, going from <fr:tex display="inline"><![CDATA[n]]></fr:tex> to <fr:tex display="inline"><![CDATA[n^2]]></fr:tex>.</html:p>
                    <html:p>The following table (excerpted from <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">a 50-year-old book</fr:link>!)
illustrates the effect of various time complexities.  The left-hand column (dubbed "complexity")
is defind as how many milliseconds are required to process an input of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
The other entries show the maximum size of <fr:tex display="inline"><![CDATA[n]]></fr:tex> that can be processed in the given time (one
second, minute or hour).</html:p>
                    <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>gain</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td><fr:tex display="inline"><![CDATA[\times  60]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td><fr:tex display="inline"><![CDATA[\times  41]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td><fr:tex display="inline"><![CDATA[\times  8]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td><fr:tex display="inline"><![CDATA[\times  4]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td><fr:tex display="inline"><![CDATA[+6]]></fr:tex></html:td></html:tr>
</html:table>
                    <html:p>The table illustrates how large an input can be processed as a function
of time.  As we increase the computer time per input from one second to one
minute and then to one hour, the size of the input increases accordingly.</html:p>
                    <html:p>The top two rows (complexities <fr:tex display="inline"><![CDATA[n]]></fr:tex> and <fr:tex display="inline"><![CDATA[n \lg  n]]></fr:tex>) increase rapidly: for <fr:tex display="inline"><![CDATA[n]]></fr:tex>, by
a factor of 60 per column.  The bottom two start out close together, but <fr:tex display="inline"><![CDATA[n^3]]></fr:tex> (which
grows by a factor of 3.9) pulls well away from <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> (whose growth is only
additive).  If an algorithm’s complexity is exponential then it can never
handle large inputs, even if it is given huge resources.  On the other hand,
suppose the complexity has the form <fr:tex display="inline"><![CDATA[n^c]]></fr:tex>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is a constant.  (We say
the complexity is <html:em>polynomial</html:em>.)  Doubling the argument then increases the
cost by a constant factor.  That is much better, though if <fr:tex display="inline"><![CDATA[c>3]]></fr:tex> the algorithm
may not be considered practical.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation-facts/</fr:uri>
                    <fr:display-uri>focs-o-notation-facts</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-o-notation-facts/</fr:route>
                    <fr:title text="Simple Facts About O Notation">Simple Facts About O Notation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
 O(2g(n)) & \text { is the same as } O(g(n)) \\
 O(\log _{10}n) & \text { is the same as } O(\ln  n)  \\
 O(n^2+50n+36) & \text { is the same as } O(n^2) \\[1.5ex]
 O(n^2) & \text { is contained in }  O(n^3) \\
 O(2^n) & \text { is contained in }  O(3^n)  \\
 O(\log  n) & \text { is contained in } O(\sqrt  n)
\end {aligned}
]]></fr:tex>
                    <html:p><fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> lets us reason about the costs of algorithms easily.</html:p>
                    <html:ul><html:li>Constant factors such as the <fr:tex display="inline"><![CDATA[2]]></fr:tex> in <fr:tex display="inline"><![CDATA[O(2g(n))]]></fr:tex> drop out: we can use <fr:tex display="inline"><![CDATA[O(g(n))]]></fr:tex> with twice the value of <fr:tex display="inline"><![CDATA[c]]></fr:tex> in the definition.</html:li>
  <html:li>Because constant factors drop out, the base of logarithms is irrelevant.</html:li>
  <html:li>Insignificant terms drop out.  To see that <fr:tex display="inline"><![CDATA[O(n^2+50n+36)]]></fr:tex> is the same as <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>, consider that <fr:tex display="inline"><![CDATA[n^2+50n+36/n^2]]></fr:tex> converges to 1 for increasing <fr:tex display="inline"><![CDATA[n]]></fr:tex>. In fact, <fr:tex display="inline"><![CDATA[n^2+50n+36 \le  2n^2]]></fr:tex> for <fr:tex display="inline"><![CDATA[n\ge  51]]></fr:tex>, so can double the constant factor</html:li></html:ul>
                    <html:p>If <fr:tex display="inline"><![CDATA[c]]></fr:tex> and <fr:tex display="inline"><![CDATA[d]]></fr:tex> are constants (that is, they are independent of <fr:tex display="inline"><![CDATA[n]]></fr:tex>) with <fr:tex display="inline"><![CDATA[0 < c < d]]></fr:tex> then</html:p>
                    <html:ul><html:li><fr:tex display="inline"><![CDATA[O(n^c)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(n^d)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(c^n)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(d^n)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> is contained in <fr:tex display="inline"><![CDATA[O(n^c)]]></fr:tex></html:li></html:ul>
                    <html:p>To say that <fr:tex display="inline"><![CDATA[O(c^n)]]></fr:tex> <html:em>is contained in</html:em> <fr:tex display="inline"><![CDATA[O(d^n)]]></fr:tex> means that the former gives
a tighter bound than the latter.  For example, if <fr:tex display="inline"><![CDATA[f(n)=O(2^n)]]></fr:tex> then
<fr:tex display="inline"><![CDATA[f(n)=O(3^n)]]></fr:tex> trivially, but the converse does not hold.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recurrences/</fr:uri>
                    <fr:display-uri>focs-recurrences</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-recurrences/</fr:route>
                    <fr:title text="Some Simple Recurrence Relations">Some Simple Recurrence Relations</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider a function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> that has a cost we want to bound using <fr:link href="/~avsm2/fcs/focs-def-o-notation/" title="O notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-o-notation/" display-uri="focs-def-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link>.
A typical <html:em>base case</html:em> is <fr:tex display="inline"><![CDATA[T(1)=1]]></fr:tex>.  Some <html:em>recurrences</html:em> are:</html:p>
                    <html:table>
  <html:tr><html:th>Equation</html:th><html:th>Complexity</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:td></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex></html:td><html:td><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex></html:td></html:tr>
</html:table>
                    <html:p>To analyse a function, inspect its OCaml declaration.  Recurrence equations for
the cost function <fr:tex display="inline"><![CDATA[T(n)]]></fr:tex> can usually be read off.  Since we ignore constant
factors, we can give the base case a cost of one unit.  Constant work done in
the recursive step can also be given unit cost; since we only need an upper
bound, this unit represents the larger of the two actual costs.  We could use
other constants if it simplifies the algebra.</html:p>
                    <html:p>For example, recall our function <fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec nsum n =
    if n = 0 then
      0
    else
      n + nsum (n - 1)
val nsum : int -> int = <fun>]]></html:pre>
                    <html:p>Given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, it performs a constant amount of work (an addition and
subtraction) and calls itself recursively with argument <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  We get the
recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+1]]></fr:tex>.  The closed form is
clearly <fr:tex display="inline"><![CDATA[T(n)=n+1]]></fr:tex>, as we can easily verify by substitution.  The cost is
<html:em>linear</html:em>.</html:p>
                    <html:p>This function, given <fr:tex display="inline"><![CDATA[n+1]]></fr:tex>, calls <html:code>nsum</html:code>, performing <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> work.
Again ignoring constant factors, we can say that this call takes exactly <fr:tex display="inline"><![CDATA[n]]></fr:tex>
units.</html:p>
                    <html:pre><![CDATA[# let rec nsumsum n =
    if n = 0 then
      0
    else
      nsum n + nsumsum (n - 1)
val nsumsum : int -> int = <fun>]]></html:pre>
                    <html:p>We get the recurrence equations <fr:tex display="inline"><![CDATA[T(0)=1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>.  It is easy to
see that <fr:tex display="inline"><![CDATA[T(n)=(n-1)+\cdots +1=n(n-1)/2=O(n^2)]]></fr:tex>.  The cost is
<html:em>quadratic</html:em>.</html:p>
                    <html:p>The function <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> divides its input <fr:tex display="inline"><![CDATA[n]]></fr:tex> into two, with
the recurrence equation <fr:tex display="inline"><![CDATA[T(n) = T(n/2)+1]]></fr:tex>.  Clearly <fr:tex display="inline"><![CDATA[T(2^n)=n+1]]></fr:tex>, so
<fr:tex display="inline"><![CDATA[T(n)=O(\log  n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-summary/</fr:uri>
                    <fr:display-uri>focs-sorting-summary</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sorting-summary/</fr:route>
                    <fr:title text="Summary of Sorting Algorithms">Summary of Sorting Algorithms</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Optimal is <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">Insertion sort</fr:link>: simple to code; too slow (quadratic) [174 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-quicksort/" title="Quicksort: The Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/" display-uri="focs-quicksort" type="local">Quicksort</fr:link>: fast on average; quadratic in worst case [0.53 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link>: optimal in theory; often slower than quicksort [1.4 secs]</html:li>
  <html:li><html:em>Match the algorithm to the application</html:em></html:li></html:ul>
                    <html:p>Quicksort’s worst case cannot be ignored.  For large <fr:tex display="inline"><![CDATA[n]]></fr:tex>, a complexity of
<fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> is catastrophic.  Mergesort has an <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> worst case running
time, which is optimal, but it is typically slower than quicksort for random
data.</html:p>
                    <html:p>Non-comparison sorting deserves mentioning.  We can sort a large number of
small integers using their radix representation in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time.  This result
does not contradict the comparison-counting argument because comparisons are
not used at all.  Linear time is achievable only if the greatest integer is
fixed in advance; as <fr:tex display="inline"><![CDATA[n]]></fr:tex> goes to infinity, increasingly many of the items
are the same.  It is a simple special case.</html:p>
                    <html:p>Many other sorting algorithms exist. A few are outlined in <fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">the exercises</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/</fr:uri>
                    <fr:display-uri>focs-merge-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge-sort/</fr:route>
                    <fr:title text="Top-down Merge sort">Top-down Merge sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec tmergesort = function
    | [] -> []
    | [x] -> [x]
    | xs ->
        let k = List.length xs / 2 in
        let l = tmergesort (take k xs) in
        let r = tmergesort (drop k xs) in
        merge (l, r)
val tmergesort : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons in worst case</html:p>
                    <html:p>Mergesort’s <html:em>divide</html:em> stage divides the input not by choosing a pivot (as
in <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>) but by simply counting out half of the elements.  The
<html:em>conquer</html:em> stage again involves recursive calls, and the <html:em>combine</html:em>
stage involves merging.  Function <html:code>tmergesort</html:code> takes roughly 1.4
seconds to sort the list <html:code>rs</html:code>.</html:p>
                    <html:p>In the worst case, mergesort does <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons, with the same
recurrence equation as in quicksort’s average case.  Because <fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>take</html:code></fr:link> and
<fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>drop</html:code></fr:link> divide the input in two equal parts (they differ at most by
one element), we always have <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>.</html:p>
                    <html:p>Quicksort is nearly 3 times as fast in the example.  But it risks a
quadratic worst case!  Merge sort is safe but slow.  So which algorithm is
best?</html:p>
                    <html:p>We have seen a <html:em>top-down</html:em> mergesort.  <html:em>Bottom-up</html:em> algorithms also
exist.  They start with a list of one-element lists and repeatedly merge
adjacent lists until only one is left.  A refinement, which exploits any
initial order among the input, is to start with a list of increasing or
decreasing runs of input items.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-4/</fr:uri>
                    <fr:display-uri>focs-ex-2-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-2-4/</fr:route>
                    <fr:title text="Exercises › A tighter recurrence bound"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › A tighter recurrence bound</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Find an upper bound for the recurrence given by <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+1]]></fr:tex>.  You should be
able to find a tighter bound than <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-3/</fr:uri>
                    <fr:display-uri>focs-ex-5-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-3/</fr:route>
                    <fr:title text="Exercises › Complexity of bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of bubble sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another sorting algorithm (bubble sort) consists of looking at adjacent pairs of elements,
exchanging them if they are out of order and repeating this process until no more exchanges are
possible. State, with justification, the time complexity of this approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-1/</fr:uri>
                    <fr:display-uri>focs-ex-5-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-1/</fr:route>
                    <fr:title text="Exercises › Complexity of selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of selection sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another sorting algorithm (selection sort) consists of looking at the elements to be sorted,
identifying and removing a minimal element, which is placed at the head of the result. The tail is
obtained by recursively sorting the remaining elements. State, with justification, the time
complexity of this approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-5/</fr:uri>
                    <fr:display-uri>focs-ex-4-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-5/</fr:route>
                    <fr:title text="Exercises › Counting ways of making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Counting ways of making change</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the number of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">ways of making change</fr:link> for <fr:tex display="inline"><![CDATA[n]]></fr:tex> (ignoring order) is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> if there are two
legal coin values. What if there are three, four, … coin values?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-2/</fr:uri>
                    <fr:display-uri>focs-ex-2-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-2-2/</fr:route>
                    <fr:title text="Exercises › Extending the complexity table"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Extending the complexity table</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Add a column to the <fr:link href="/~avsm2/fcs/focs-sillysum/" title="Silly Summing the First n Integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sillysum/" display-uri="focs-sillysum" type="local">table of complexities</fr:link> from <html:em>The Design and Analysis of Computer Algorithms</html:em> with the heading <html:em>60 hours:</html:em></html:p>
                    <html:table>
  <html:tr><html:th>complexity</html:th><html:th>1 second</html:th><html:th>1 minute</html:th><html:th>1 hour</html:th><html:th>60 hours</html:th></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n]]></fr:tex></html:td><html:td>1000</html:td><html:td>60 000</html:td><html:td>3 600 000</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n \log  n]]></fr:tex></html:td><html:td>140</html:td><html:td>4 895</html:td><html:td>204 095</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{2}]]></fr:tex></html:td><html:td>31</html:td><html:td>244</html:td><html:td>1 897</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[n^{3}]]></fr:tex></html:td><html:td>10</html:td><html:td>39</html:td><html:td>153</html:td><html:td /></html:tr>
  <html:tr><html:td><fr:tex display="inline"><![CDATA[2^{n}]]></fr:tex></html:td><html:td>9</html:td><html:td>15</html:td><html:td>21</html:td><html:td /></html:tr>
</html:table>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-2/</fr:uri>
                    <fr:display-uri>focs-ex-3-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-2/</fr:route>
                    <fr:title text="Exercises › Last element of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Last element of a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to return the last element of a non-empty list. How efficiently can this be done?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-7/</fr:uri>
                    <fr:display-uri>focs-ex-7-7</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-7/</fr:route>
                    <fr:title text="Exercises › Linear traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Linear traversals</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>preord</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>inord</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>postord</html:code></fr:link> all take linear time in the size of the
tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-6/</fr:uri>
                    <fr:display-uri>focs-ex-7-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-6/</fr:route>
                    <fr:title text="Exercises › Quadratic traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Quadratic traversals</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>preorder</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>postorder</html:code></fr:link> all require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time in the worst
case, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the size of the tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-4/</fr:uri>
                    <fr:display-uri>focs-ex-10-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-4/</fr:route>
                    <fr:title text="Exercises › Search with a branching factor near one"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Search with a branching factor near one</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><fr:link href="/~avsm2/fcs/focs-iterative-deepening/" title="Iterative deepening: Another Exhaustive Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/" display-uri="focs-iterative-deepening" type="local">Iterative deepening</fr:link> is inappropriate if <fr:tex display="inline"><![CDATA[b\approx 1]]></fr:tex>, where <fr:tex display="inline"><![CDATA[b]]></fr:tex> is the branching factor. What search
strategy is appropriate in this case?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2-3/</fr:uri>
                    <fr:display-uri>focs-ex-2-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-2-3/</fr:route>
                    <fr:title text="Exercises › Simplifying sums in O notation"><fr:link href="/~avsm2/fcs/focs-ex-2/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-2/" display-uri="focs-ex-2" type="local">Exercises</fr:link> › Simplifying sums in O notation</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Let <fr:tex display="inline"><![CDATA[g_1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[g_k]]></fr:tex> be functions such that <fr:tex display="inline"><![CDATA[g_i(n)\ge 0]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=1]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[k]]></fr:tex> and all sufficiently
large <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>Show that if <fr:tex display="inline"><![CDATA[f(n) = O(a_1 g_1(n)+\cdots +a_k g_k(n))]]></fr:tex> then <fr:tex display="inline"><![CDATA[f(n) = O(g_1(n)+\cdots +g_k(n))]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-1/</fr:uri>
                    <fr:display-uri>focs-ex-10-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-1/</fr:route>
                    <fr:title text="Exercises › Tree-based queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Tree-based queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Suppose that we have an implementation of queues, based on <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>, such that each operation
takes logarithmic time in the worst case. Outline the advantages and drawbacks of such an
implementation compared with one presented above.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-lists/</fr:uri>
                <fr:display-uri>focs-topic-lists</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-lists/</fr:route>
                <fr:title text="Lists">Lists</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/</fr:uri>
                    <fr:display-uri>focs-change-all</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-all/</fr:route>
                    <fr:title text="All Ways of Making Change">All Ways of Making Change</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Now we generalise the problem to return the list of <html:em>all possible ways</html:em> of making change,
and write a new <html:code>change</html:code> function.</html:p>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                    <html:p>Look at the type: the result is now a list of lists.
The code will also never raise <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>.  It expresses failure by returning an
empty list of solutions: it returns <html:code>[]</html:code> if the till is empty and the
amount is nonzero.</html:p>
                    <html:p>If the amount is zero, then there is only one way of making change;
the result should be <html:code><![CDATA[[[]]]]></html:code>.  This is success in the base case.</html:p>
                    <html:p>In nontrivial cases, there are two sources of solutions: to use a coin (if
possible) and decrease the amount accordingly, or to remove the current coin
value from consideration.</html:p>
                    <html:p>The function <html:code>allc</html:code> is declared locally in order to make use
of <html:code>c</html:code>, the current coin.  It adds an extra <html:code>c</html:code> to all the
solutions returned by the recursive call to make change for <html:code>amt - c</html:code>.</html:p>
                    <html:p>Observe the naming convention: <html:code>cs</html:code> is a list of coins, while
<html:code>css</html:code> is a list of such lists.  The trailing ‘s’ is suggestive of a
plural.</html:p>
                    <html:p>This complicated program, and the even trickier one on the next slide, are
included as challenges.  Are you enthusiastic enough to work them out?  We
shall revisit the “making change” task later to illustrate <fr:link href="/~avsm2/fcs/focs-change-exceptions/" title="Making Change with Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/" display-uri="focs-change-exceptions" type="local">exception-handling</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-faster/</fr:uri>
                    <fr:display-uri>focs-change-faster</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-faster/</fr:route>
                    <fr:title text="All Ways of Making Change — Faster!">All Ways of Making Change — Faster!</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec change till amt chg chgs =
    match till, amt with
    | _       , 0   -> chg::chgs
    | []      , _   -> chgs
    | c::till , amt -> if amt < 0 then chgs
                       else change (c::till) (amt - c) (c::chg)
                                   (change till amt chg chgs)
val change : int list -> int -> int list -> int list list -> int list list =
  <fun>]]></html:pre>
                    <html:p>We’ve added <html:em>another</html:em> accumulating parameter!  Repeatedly improving simple code
is called <html:em>stepwise refinement</html:em>.</html:p>
                    <html:p>Two extra arguments eliminate many <html:code>::</html:code> and append operations from the previous
slide’s <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local"><html:code>change</html:code></fr:link> function.  The first, <html:code>chg</html:code>, accumulates the coins chosen so
far; one evaluation of <html:code>c::chg</html:code> replaces many evaluations of <html:code>allc</html:code>.  The
second, <html:code>chgs</html:code>, accumulates the list of solutions so far; it avoids the need
for <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link>.  This version runs several times faster than the previous one.</html:p>
                    <html:p>Making change is still extremely slow for an obvious reason: the number of
solutions grows rapidly in the amount being changed.  Using 50, 20, 10, 5,
2 and 1, there are 4366 ways of expressing 99.</html:p>
                    <html:p>Our three change functions illustrate a basic technique: program development
by stepwise refinement.  Begin by writing a very simple program and add
requirements individually.  Add efficiency refinements last of all.
Even if the simpler program cannot be included in the next version and has
to be discarded, one has learned about the task by writing it.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/</fr:uri>
                    <fr:display-uri>focs-making-change</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-making-change/</fr:route>
                    <fr:title text="An Application: Making Change">An Application: Making Change</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider a till that has unlimited supplies of coins.  The largest coins should be tried
first, to avoid giving change all in pennies.  The list of legal coin values,
called <html:code>till</html:code>, is given in descending order, such as 50, 20, 10, 5,
2 and 1.  (Recall that the <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">head of a list</fr:link> is the element most easily reached.)
The code for <html:code>change</html:code> is based on simple observations:</html:p>
                    <html:ul><html:li>Change for zero consists of no coins at all.  (Note the pattern of <html:code>0</html:code> in the first clause.)</html:li>
  <html:li>For a nonzero amount, try the largest available coin.  If it is small enough, use it and decrease the amount accordingly.</html:li>
  <html:li>Exclude from consideration any coins that are too large.</html:li></html:ul>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise (Failure "no more coins!")
    | c::till, amt -> if amt < c then change till amt
                      else c :: change (c::till) (amt - c)
val change : int list -> int -> int list = <fun>]]></html:pre>
                    <html:p>Although nobody considers making change for zero, this is the simplest way to
make the algorithm terminate.  Most iterative procedures become simplest if,
in their base case, they do nothing.  A base case of one instead of zero is
often a sign of a novice programmer.</html:p>
                    <html:ul><html:li>The <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> <html:em>terminates</html:em> when <html:code>amt = 0</html:code>.</html:li>
  <html:li>Tries the <html:em>largest coin first</html:em> to use large coins.</html:li>
  <html:li>The algorithm is <html:em>greedy</html:em> and can fail!</html:li></html:ul>
                    <html:p>The function can terminate either with success or failure.  It fails by
raising exception <html:code>Failure</html:code> namely if <html:code>till</html:code> becomes empty while <html:code>amt</html:code> is still nonzero.
(<fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">Exceptions</fr:link> will be discussed later.)</html:p>
                    <html:p>Unfortunately, failure can occur even when change can be made.  The greedy
"largest coin first" approach is to blame.  Suppose we have coins of values 5
and 2, and must make change for 6; the only way is <fr:tex display="inline"><![CDATA[6=2+2+2]]></fr:tex>, ignoring the 5.
<html:em>Greedy algorithms</html:em> are often effective, but not here.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-append-free/</fr:uri>
                    <fr:display-uri>focs-quicksort-append-free</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort-append-free/</fr:route>
                    <fr:title text="Append-Free Quicksort">Append-Free Quicksort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quik = function
    | ([], sorted) -> sorted
    | ([x], sorted) -> x::sorted
    | a::bs, sorted ->
       let rec part = function
         | l, r, [] -> quik (l, a :: quik (r, sorted))
         | l, r, x::xs ->
             if x <= a then
               part (x::l, r, xs)
             else
               part (l, x::r, xs)
       in
       part ([], [], bs)
val quik : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>The list <html:code>sorted</html:code> accumulates the result in the <html:em>combine</html:em> stage of
the quicksort algorithm.  We have again used the standard technique for
<fr:link href="/~avsm2/fcs/focs-rev/" title="Reversing a List in O(n)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/" display-uri="focs-rev" type="local">eliminating append</fr:link>.  Calling <html:code>quik(xs, sorted)</html:code> reverses the elements of
<html:code>xs</html:code> and prepends them to the list <html:code>sorted</html:code>.</html:p>
                    <html:p>Looking closely at <html:code>part</html:code>, observe that <html:code>quik(r, sorted)</html:code> is
performed first.  Then <html:code>a</html:code> is consed to this sorted list.  Finally,
<html:code>quik</html:code> is called again to sort the elements of <html:code>l</html:code>.</html:p>
                    <html:p>The speedup is significant.  An imperative quicksort coded in Pascal (taken
from <fr:link href="https://algs4.cs.princeton.edu/20sorting/" type="external">Sedgewick</fr:link>) is just slightly faster than function
<html:code>quik</html:code>.  The near-agreement is surprising because the computational overheads
of lists exceed those of arrays.  In realistic applications, comparisons are
the dominant cost and the overheads matter even less.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/</fr:uri>
                    <fr:display-uri>focs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-append/</fr:route>
                    <fr:title text="Append: List Concatenation">Append: List Concatenation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec append xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> x :: append xs ys
val append : 'a list -> 'a list -> 'a list = <fun>
# append [1; 2; 3] [4]
- : int list = [1; 2; 3; 4]
# let (@) = append
val ( @ ) : 'a list -> 'a list -> 'a list = <fun>
# [1; 2; 3] @ [4]
- : int list = [1; 2; 3; 4]]]></html:pre>
                    <html:p>Patterns can be as complicated as we like.  Here, the two patterns are
<html:code>[], ys</html:code> and <html:code>x::xs, ys</html:code>.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {append }[1; 2; 3] [4] \Rightarrow  &\; 1 :: \text {append }[2; 3]\;[4] \\
  \Rightarrow  &\; 1 :: (2 :: \text {append }[3]\;[4]) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: \text {append }[]\;[4])) \\
  \Rightarrow  &\; 1 :: (2 :: (3 :: [4])) \ [1; 2; 3; 4]
\end {aligned}
]]></fr:tex>
                    <html:p>Here is how append might be declared, also noting that we have defined <html:code>@</html:code> as
an infix operator that is a more convenient way to call <html:code>append</html:code> on two lists.
However, this function is also not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It scans its first
argument, sets up a string of <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code> operations</fr:link> (<html:code>::</html:code>) and finally does them.</html:p>
                    <html:p>It uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its first argument.
<html:em>Its costs are independent of its second argument.</html:em></html:p>
                    <html:p>An accumulating argument could make it iterative, but with considerable
complication.  The iterative version would still require <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space and time
because concatenation requires copying all the elements of the first list.
Therefore, we cannot hope for asymptotic gains; at best we can decrease the
constant factor involved in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>, but complicating the code is likely to
increase that factor.  Never add an accumulator merely out of habit.</html:p>
                    <html:p>Note append’s <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic type</fr:link>. It tells us that two lists can be joined if
their element types agree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-applications/</fr:uri>
                    <fr:display-uri>focs-predicate-applications</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-applications/</fr:route>
                    <fr:title text="Applications of the Predicate Functionals">Applications of the Predicate Functionals</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let member y xs =
    exists (fun x -> x=y) xs
val member : 'a -> 'a list -> bool = <fun>
# let inter xs ys =
    filter (fun x -> member x ys) xs
val inter : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Testing whether two lists have no common elements</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let disjoint xs ys =
    all (fun x -> all (fun y -> x<>y) ys) xs
val disjoint : 'a list -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The Lists lecture presented the function <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link>, which tests whether a
specified value can be found as a list element, and <html:code>inter</html:code>, which returns the
“intersection” of two lists: the list of elements they have in common.</html:p>
                    <html:p>But remember: the purpose of list <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> is not to replace the
declarations of popular functions, which probably are available already.  It is
to eliminate the need for separate declarations of ad-hoc functions.  When they
are nested, like the calls to <html:code>all</html:code> in <html:code>disjoint</html:code> above, the
inner functions are almost certainly one-offs, not worth declaring separately.</html:p>
                    <html:p>Our primitives themselves can be seen as a programming language.  Part of the
task of programming is to extend our programming language with notation for
solving the problem at hand.  The levels of notation that we define should
correspond to natural <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">levels of abstraction</fr:link> in the problem domain.</html:p>
                    <html:p>Historical Note:
Alonzo Church’s <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus gave a simple syntax, <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-notation,
for expressing functions.  It is the direct precursor of OCaml’s
<html:code>fun</html:code>-notation.  It was soon shown that his system was equivalent in
computational power to Turing machines, and <html:em>Church’s thesis</html:em> states that
this defines precisely the set of functions that can be computed effectively.</html:p>
                    <html:p>The <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus had a tremendous influence on the design of functional
programming languages.  McCarthy’s Lisp was something of a false start; it
interpreted variable binding incorrectly, an error that stood for some 20
years.  But in 1966, Peter Landin (of Queen Mary College, University of London)
sketched out the main features of functional languages.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/</fr:uri>
                    <fr:display-uri>focs-tree-traversal</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal/</fr:route>
                    <fr:title text="Aside: Traversing Trees (3 Methods)">Aside: Traversing Trees (3 Methods)</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec preorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      [v] @ preorder t1 @ preorder t2
val preorder : 'a tree -> 'a list = <fun>
# let rec inorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      inorder t1 @ [v] @ inorder t2
val inorder : 'a tree -> 'a list = <fun>
# let rec postorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      postorder t1 @ postorder t2 @ [v]
val postorder : 'a tree -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Tree traversal</html:em> means examining each node of a tree in some order.  <fr:link href="https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming" type="external">D. E.
Knuth</fr:link> has
identified three forms of tree traversal: preorder, inorder and
postorder.  We can code these “visiting orders” as functions
that convert trees into lists of labels.  Algorithms based on these notions
typically perform some action at each node; the functions above simply copy
the nodes into lists.  Consider the tree:</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmic3wbal56lpqlso6xcqsl6jfrutwygavrn3xds7c6ieywfjr7qdhm.svg" />
                    </html:figure>
                    <html:ul><html:li><html:code>preorder</html:code> visits the label first (“Polish notation”), yielding <html:code>ABDECFG</html:code></html:li>
<html:li><html:code>inorder</html:code> visits the label midway, yielding <html:code>DBEAFCG</html:code></html:li>
<html:li><html:code>postorder</html:code> visits the label last (“Reverse Polish”), yielding <html:code>DEBFGCA</html:code>. You might be familiar with this concept if you own an ancient RPN calculator!</html:li></html:ul>
                    <html:p>What is the use of <html:code>inorder</html:code>? Consider applying it to a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>: the
result is a sorted list of pairs. We could use this, for example, to merge two
binary search trees. It is not difficult to transform a sorted list of pairs
into a binary search tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/</fr:uri>
                    <fr:display-uri>focs-bfs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-append/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Append">Breadth-First Tree Traversal — Using Append</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nbreadth = function
  | [] -> []
  | Lf :: ts -> nbreadth ts
  | Br (v, t, u) :: ts ->
      v :: nbreadth (ts @ [t; u])
val nbreadth : 'a tree list -> 'a list = <fun>]]></html:pre>
                    <html:p>Keeps an <html:em>enormous queue</html:em> of nodes of search, and is a wasteful use of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.</html:p>
                    <html:p>Breadth-first search can be inefficient, this naive implementation especially
so.  When the search is at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> of the tree, the list contains all the
remaining trees at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex>, followed by the subtrees (all at depth <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>) of
the trees that have already been visited.  At depth 10, the list could already
contain 1024 elements.  It requires a lot of space, and aggravates this with a
gross misuse of append.  Evaluating <html:code>ts@[t, u]</html:code> copies the long list
<html:code>ts</html:code> just to insert two elements.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/</fr:uri>
                    <fr:display-uri>focs-zip</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-zip/</fr:route>
                    <fr:title text="Building a List of Pairs">Building a List of Pairs</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec zip xs ys =
    match xs, ys with
    | (x::xs, y::ys) -> (x, y) :: zip xs ys
    | _ -> []
val zip : 'a list -> 'b list -> ('a * 'b) list = <fun>]]></html:pre>
                    <fr:tex display="block"><![CDATA[\left .[x_1,\ldots ,x_n]\atop 
         [y_1,\ldots ,y_n]\right \}\;\longmapsto \;[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex>
                    <html:p>The <html:em>wildcard</html:em> pattern <html:code>_</html:code> matches <html:em>anything</html:em>. We could have written a
variable such as <html:code>p</html:code> instead, but the wildcard reminds us that the
relevant clause ignores this argument.</html:p>
                    <html:p>The patterns are also tested in order of their definitions: first
<html:code>(x::xs, y::ys)</html:code>, then <html:code>_</html:code>.</html:p>
                    <html:p>A list of pairs of the form <fr:tex display="inline"><![CDATA[[(x_1,y_1),\ldots ,(x_n,y_n)]]]></fr:tex> associates each
<fr:tex display="inline"><![CDATA[x_i]]></fr:tex> with <fr:tex display="inline"><![CDATA[y_i]]></fr:tex>.  Conceptually, a telephone directory could be regarded as
such a list, where <fr:tex display="inline"><![CDATA[x_i]]></fr:tex> ranges over names and <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> over the corresponding
telephone number.  <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link> in such a list can find the <fr:tex display="inline"><![CDATA[y_i]]></fr:tex> associated
with a given <fr:tex display="inline"><![CDATA[x_i]]></fr:tex>, or vice versa—very slowly.</html:p>
                    <html:p>In other cases, the <fr:tex display="inline"><![CDATA[(x_i,y_i)]]></fr:tex> pairs might have been generated by applying a
function to the elements of another list <fr:tex display="inline"><![CDATA[[z_1,\ldots ,z_n]]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# let rec unzip = function
   | [] -> ([], [])
   | (x, y)::pairs ->
       let xs, ys = unzip pairs in
       (x::xs, y::ys)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>Given a list of pairs, <html:code>unzip</html:code> has to build <html:em>two</html:em> lists of
results, which is awkward using recursion.  The version shown above uses the
<html:em>local binding</html:em> <html:code>let p = </html:code><fr:tex display="inline"><![CDATA[\;E_1\;]]></fr:tex><html:code> in </html:code><fr:tex display="inline"><![CDATA[\;E_2]]></fr:tex>,
where the value of <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> is bound to the variable <html:code>p</html:code> within <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>. The
let-construct counts as an expression and can be used (perhaps wrapped
within parentheses) wherever an expression is expected.</html:p>
                    <html:p>Note especially the phrase <html:code>let xs, ys = unzip pairs</html:code>
which binds <html:code>xs</html:code> and <html:code>ys</html:code> to the results of the recursive call.
In general, the phrase <html:code>let P = E</html:code> matches the
pattern <fr:tex display="inline"><![CDATA[P]]></fr:tex> against the value of expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It binds all the variables
in <fr:tex display="inline"><![CDATA[P]]></fr:tex> to the corresponding values.</html:p>
                    <html:p>The functions <html:code>zip</html:code> and <html:code>unzip</html:code> build and take apart lists of
pairs: <html:code>zip</html:code> pairs up corresponding list elements and <html:code>unzip</html:code>
inverts this operation.  Their types reflect what they do:</html:p>
                    <html:pre><![CDATA[# zip
- : 'a list -> 'b list -> ('a * 'b) list = <fun>
# unzip
- : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>If the lists are of unequal length, <html:code>zip</html:code> discards surplus items at the
end of the longer list.  Its first pattern only matches a pair of non-empty
lists.  The second pattern is just a wildcard and could match anything.  OCaml
tries the clauses in the order given, so the first pattern is tried first.
The second only gets arguments where at least one of the lists is empty.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-unzip/</fr:uri>
                    <fr:display-uri>focs-unzip</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-unzip/</fr:route>
                    <fr:title text="Building a Pair of Results">Building a Pair of Results</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Here is a version of <html:code>unzip</html:code> that replaces the local declaration by a
function <html:code>conspair</html:code> for taking apart the pair of lists in the
recursive call.  It defines the same
computation as the previous version of <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local"><html:code>unzip</html:code></fr:link> and is possibly clearer,
but not every local binding can be eliminated as easily.</html:p>
                    <html:pre><![CDATA[# let conspair ((x, y), (xs, ys)) = (x::xs, y::ys)
val conspair : ('a * 'b) * ('a list * 'b list) -> 'a list * 'b list = <fun>
# let rec unzip = function
    | [] -> ([], [])
    | xy :: pairs -> conspair (xy, unzip pairs)
val unzip : ('a * 'b) list -> 'a list * 'b list = <fun>]]></html:pre>
                    <html:p>Making the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> yields <html:code>revUnzip</html:code> below, which is
very simple.  Iteration can construct many results at once in different
argument positions.  Both output lists are built in reverse order, which can
be corrected by reversing the input to <html:code>revUnzip</html:code>.  The total costs
will probably exceed those of <html:code>unzip</html:code> despite the advantages of
iteration.</html:p>
                    <html:pre><![CDATA[# let rec revUnzip = function
    | ([], xs, ys) -> (xs, ys)
    | ((x, y)::pairs, xs, ys) ->
        revUnzip (pairs, x::xs, y::ys)
val revUnzip : ('a * 'b) list * 'a list * 'b list -> 'a list * 'b list =
  <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nlength/</fr:uri>
                    <fr:display-uri>focs-nlength</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nlength/</fr:route>
                    <fr:title text="Computing the Length of a List">Computing the Length of a List</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nlength = function
  | [] -> 0
  | x :: xs -> 1 + nlength xs
val nlength : 'a list -> int = <fun>
# nlength []
- : int = 0
# nlength [5; 6; 7]
- : int = 3]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nlength }[a; b; c] \Rightarrow  &\; 1 + \text {nlength }[b; c] \\
   \Rightarrow  &\; 1 + (1 + \text {nlength }[c]) \\
   \Rightarrow  &\; 1 + (1 + (1 + \text {nlength }[])) \\
   \Rightarrow  &\; 1 + (1 + (1 + 0)) \\
   \Rightarrow  &\; \ldots  \;\; 3
\end {aligned}
]]></fr:tex>
                    <html:p>Most list processing involves <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  This is a simple example; patterns
can be more complex.  Observe the use of a vertical bar <html:code>|</html:code> to separate the function’s
clauses.  We have <html:em>one</html:em> function declaration that handles two cases.
To understand its role, consider the following faulty code:</html:p>
                    <html:pre><![CDATA[# let rec nlength [] = 0
Line 1, characters 17-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
_::_
val nlength : 'a list -> int = <fun>
# let rec nlength (x::xs) = 1 + nlength xs
Line 1, characters 17-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val nlength : 'a list -> int = <fun>]]></html:pre>
                    <html:p>These are two declarations, not one.  First we declare <html:code>nlength</html:code> to be a
function that handles only empty lists.  Then we redeclare it to be a function
that handles only non-empty lists; it can never deliver a result.  We see that
a second <html:code>let</html:code> declaration replaces any previous one rather than extending it
to cover new cases.</html:p>
                    <html:p>Now, let us return to our original declaration of <html:code>nlength</html:code>.  The length function
is <html:em><fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link></html:em> and applies to <html:em>all</html:em> lists regardless of element
type!  Most programming languages lack such flexibility.</html:p>
                    <html:p>Unfortunately, this length computation is naive and wasteful.  Like
<fr:link href="/~avsm2/fcs/focs-nsum/" title="Summing the first n integers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nsum/" display-uri="focs-nsum" type="local"><html:code>nsum</html:code></fr:link> earlier, it is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">tail-recursive</fr:link>.  It
uses <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> space, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the length of its input.  As usual, the
solution is to add an accumulating argument.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/</fr:uri>
                    <fr:display-uri>focs-seq-consume</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-consume/</fr:route>
                    <fr:title text="Consuming a Sequence">Consuming a Sequence</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec get n s =
    match n, s with
    | 0, _            -> []
    | n, Nil          -> []
    | n, Cons (x, xf) -> x :: get (n-1) (xf ())
val get : int -> 'a seq -> 'a list = <fun>]]></html:pre>
                    <html:p>The above code gets the first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements as a list.
<html:code>xf ()</html:code> <html:em>forces</html:em> evaluation.</html:p>
                    <html:p>The function <html:code>get</html:code> converts a sequence to a list.  It takes the
first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements; it takes all of them if <fr:tex display="inline"><![CDATA[n<0]]></fr:tex>, which can terminate only if
the sequence is finite.</html:p>
                    <html:p>In the last line of <html:code>get</html:code>, the expression <html:code>xf()</html:code> calls the tail
function, demanding evaluation of the next element.  This operation is called
<html:em>forcing</html:em> the sequence.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/</fr:uri>
                    <fr:display-uri>focs-dictionary-adt</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-dictionary-adt/</fr:route>
                    <fr:title text="Dictionaries">Dictionaries</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>lookup: find an item in the dictionary</html:li>
<html:li>update (insert): replace (store) an item in the dictionary</html:li>
<html:li>delete: remove an item from the dictionary</html:li>
<html:li>empty: the null dictionary</html:li>
<html:li>Missing: <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> for errors in <html:code>lookup</html:code> and <html:code>delete</html:code></html:li></html:ul>
                    <html:p>Ideally, an <html:em>abstract type</html:em> should provide these operations and hide the internal data structures.</html:p>
                    <html:p>A dictionary attaches values to identifiers, called “keys”.  Before choosing
the internal representation for a data structure, you need to specify the full
set of operations. In fact, here we only consider <html:code>update</html:code> (associating a
value with an identifier) and <html:code>lookup</html:code> (retrieving such a value). Deletion
is more difficult and would limit our choices. Some applications may need
additional operations, such as <html:code>merge</html:code> (combining two dictionaries). We
shall see that update can be done efficiently in a functional style, without
excessive copying.</html:p>
                    <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent dictionaries. Abstract
types can be declared in any modern programming language. Java’s <html:em>objects</html:em>
serve this role, as do OCaml’s modules. This course does not cover modules, and we
simply declare the dictionary operations individually.</html:p>
                    <html:p>An <html:em>association list</html:em> (a list of pairs) is the simplest dictionary representation.
Lookup is by <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link>, and therefore slow: <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>. Association lists are
only usable if there are few keys in use. However, they are general in that the
keys do not need a concept of ordering, only equality.</html:p>
                    <html:pre><![CDATA[# exception Missing
exception Missing
# let rec lookup a = function
  | [] -> raise Missing
  | (x, y) :: pairs ->
      if a = x then y
      else lookup a pairs
val lookup : 'a -> ('a * 'b) list -> 'b = <fun>
# let update (l, b, y) = (b, y) :: l
val update : ('a * 'b) list * 'a * 'b -> ('a * 'b) list = <fun>]]></html:pre>
                    <html:p>To enter a new <html:code>(key, value)</html:code> pair, simply “cons” it to the list with <html:code>update</html:code>.
This takes constant time, which is the best we could hope for.  But the space
requirement is huge: linear in the number of updates, not in the number of
distinct keys. Obsolete entries are never deleted: that would require first
finding them, increasing the update time from <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/</fr:uri>
                    <fr:display-uri>focs-functional-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues/</fr:route>
                    <fr:title text="Efficient Functional Queues: Code">Efficient Functional Queues: Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a queue =
  | Q of 'a list * 'a list
type 'a queue = Q of 'a list * 'a list
# let norm = function
  | Q ([], tls) -> Q (List.rev tls, [])
  | q -> q
val norm : 'a queue -> 'a queue = <fun>
# let qnull = function
  | Q ([], []) -> true
  | _ -> false
val qnull : 'a queue -> bool = <fun>
# let enq (Q (hds, tls)) x = norm (Q (hds, x::tls))
val enq : 'a queue -> 'a -> 'a queue = <fun>
# exception Empty
exception Empty
# let deq = function
  | Q (x::hds, tls) -> norm (Q (hds, tls))
  | _ -> raise Empty
val deq : 'a queue -> 'a queue = <fun>
# let qempty = Q ([], [])
val qempty : 'a queue = Q ([], [])
# let qhd = function
  | Q (x::_, _) -> x
  | _ -> raise Empty
val qhd : 'a queue -> 'a = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> of queues prevents confusion with other pairs of lists.  The empty
queue has both parts empty.</html:p>
                    <html:p>The function <html:code>norm</html:code> puts a queue into normal form, ensuring that the front part
is never empty unless the entire queue is empty.  Functions <html:code>deq</html:code> and <html:code>enq</html:code>
call <html:code>norm</html:code> to normalise their result.</html:p>
                    <html:p>Because queues are in normal form, their head is certain to be in their
front part, so <html:code>qhd</html:code> looks there.</html:p>
                    <html:p>Let us analyse the cost of an execution comprising (in any possible order) <fr:tex display="inline"><![CDATA[n]]></fr:tex>
<html:code>enq</html:code> operations and <fr:tex display="inline"><![CDATA[n]]></fr:tex> <html:code>deq</html:code> operations, starting with an
empty queue.  Each <html:code>enq</html:code> operation will perform one cons, adding an
element to the rear part.  Since the final queue must be empty, each element
of the rear part gets transferred to the front part.  The corresponding
reversals perform one cons per element.  Thus, the total cost of the series of
queue operations is <fr:tex display="inline"><![CDATA[2n]]></fr:tex> cons operations, an average of 2 per operation.  The
amortized time is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
                    <html:p>There is a catch.  The conses need not be distributed evenly; reversing a long
list could take up to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> of them.  Unpredictable delays make the approach
unsuitable for <html:em>real-time programming</html:em> where deadlines must be met.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues-idea/</fr:uri>
                    <fr:display-uri>focs-functional-queues-idea</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues-idea/</fr:route>
                    <fr:title text="Efficient Functional Queues: Idea">Efficient Functional Queues: Idea</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Represent the queue <fr:tex display="inline"><![CDATA[x_1\; x_2\; \ldots \; x_m\; y_n\; \ldots \; y_1]]></fr:tex> by any <html:em>pair of lists</html:em>
    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \; [y_1,y_2,\ldots ,y_n])]]></fr:tex></html:li>
  <html:li>Add new items to the <html:em>rear list</html:em></html:li>
  <html:li>Remove items from <html:em>front list</html:em> and if empty move <html:em>rear</html:em> to <html:em>front</html:em></html:li>
  <html:li><html:em>Amortized</html:em> time per operation is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p>Queues require efficient access at both ends: at the front, for removal, and
at the back, for insertion.  Ideally, access should take constant time,
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.  It may appear that lists cannot provide such access.  If
<html:code>enq(q, x)</html:code> performs <html:code>q@[x]</html:code>, then this operation will be <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  We
could represent queues by reversed lists, implementing <html:code>enq(q, x)</html:code> by
<html:code>x::q</html:code>, but then the <html:code>deq</html:code> and <html:code>qhd</html:code> operations would be
<fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Linear time is intolerable: a series of <fr:tex display="inline"><![CDATA[n]]></fr:tex> queue operations
could then require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time.</html:p>
                    <html:p>The solution is to represent a queue by a pair of lists, where</html:p>
                    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \, [y_1,y_2,\ldots ,y_n])]]></fr:tex>
                    <html:p>represents the queue <fr:tex display="inline"><![CDATA[x_1 x_2 \ldots  x_m y_n \ldots  y_1]]></fr:tex>.</html:p>
                    <html:p>The front part of the queue is stored in order, and the rear part is stored in
reverse order.  The <html:code>enq</html:code> operation adds elements to the rear part
using cons, since this list is reversed; thus, <html:code>enq</html:code> takes constant
time.  The <html:code>deq</html:code> and <html:code>qhd</html:code> operations look at the front part,
which normally takes constant time, since this list is stored in order.  But
sometimes <html:code>deq</html:code> removes the last element from the front part; when this
happens, it reverses the rear part, which becomes the new front part.</html:p>
                    <html:p><html:em>Amortized</html:em> time refers to the cost per operation averaged over the
lifetime of any complete execution.  Even for the worst possible execution,
the average cost per operation turns out to be constant; see the analysis
below.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/</fr:uri>
                    <fr:display-uri>focs-length</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-length/</fr:route>
                    <fr:title text="Efficiently Computing the Length of a List">Efficiently Computing the Length of a List</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec addlen n = function
  | []    -> n
  | x::xs -> addlen (n + 1) xs
val addlen : int -> 'a list -> int = <fun>
# addlen 0 [5; 6; 7]
- : int = 3]]></html:pre>
                    <html:p>Recall that the use of <html:code>function</html:code> introduces an extra (unnamed) argument
that is <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matched</fr:link> in the subsequent clauses; in this case, to break
open the list.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {addlen }0 [a; b; c] \Rightarrow  &\;  \text {addlen }1\;[b; c] \\
  \Rightarrow   &\; \text {addlen }2\;[c] \\
  \Rightarrow   &\; \text {addlen }3\;[] \\
  \Rightarrow   &\; 3
\end {aligned}
]]></fr:tex>
                    <html:p>Function <html:code>addlen</html:code> is again <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.  Its type mentions the integer
accumulator.</html:p>
                    <html:p>Now we may declare an efficient length function.  It is simply a wrapper for
<html:code>addlen</html:code>, supplying zero as the initial value of <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# let length xs = addlen 0 xs
val length : 'a list -> int = <fun>
# length [5; 6; 7; 8]
- : int = 4]]></html:pre>
                    <html:p>The recursive calls do not nest: this version is <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  It takes <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
space.  Obviously its time requirement is <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> because it takes at least <fr:tex display="inline"><![CDATA[n]]></fr:tex>
steps to find the length of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/</fr:uri>
                    <fr:display-uri>focs-equality</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-equality/</fr:route>
                    <fr:title text="Equality Tests">Equality Tests</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec member x = function
   | [] -> false
   | y::l ->
      if x = y then true
      else member x l
val member : 'a -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>All the list functions we have encountered up to now have been “<fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>”,
working for lists of any type.  Function <html:code>member</html:code> uses <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link> to report
whether or not <html:code>x</html:code> occurs in <html:code>l</html:code>.</html:p>
                    <html:p>To do this generically, it uses a special feature of OCaml known as
“polymorphic equality”, which manifests itself via the <html:code>=</html:code>, <html:code>&gt;=</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code> and
<html:code>&lt;</html:code> operators.  These operators inspect the <html:em>structure</html:em> of the values using a
consistent order.  Types you can legitimately compare this way include integers,
strings, booleans, and tuples or lists of primitive types.</html:p>
                    <html:p>More complex types can be compared this way within careful limits: recursive
structures or function values will not work (we will cover function values in
the <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Currying lecture</fr:link> later).  For now, it is sufficient to use these magic
polymorphic equality operators.  As you get more familiar with OCaml and the
use of <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">higher order functions</fr:link> (also covered in a later lecture), you will
encounter the use of explicit <html:code>compare</html:code> functions that are used to provide more
complex equality tests.</html:p>
                    <html:p>The presence of polymorphic equality is a contentious feature in OCaml.  While
it provides a great ease of use in smaller codebases, it starts to become more
dangerous when building larger OCaml-based systems.  Most large-scale users of
OCaml tend towards not using it in important code, but it is just fine for our
purposes while learning the beginning steps of computer science.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/</fr:uri>
                    <fr:display-uri>focs-transpose</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-transpose/</fr:route>
                    <fr:title text="Example: Matrix Transpose">Example: Matrix Transpose</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {pmatrix}
           a   & b & c \\
           d   & e & f
   \end {pmatrix}^T =
   \begin {pmatrix}
        a & d     \\
        b & e     \\
        c & f
\end {pmatrix}
]]></fr:tex>
                    <html:pre><![CDATA[# let rec transp = function
    | []::_ -> []
    | rows -> (map List.hd rows) ::
              (transp (map List.tl rows))
val transp : 'a list list -> 'a list list = <fun>]]></html:pre>
                    <html:p>A matrix can be viewed as a list of rows, each row a list of matrix elements.
This representation is not especially efficient compared with the conventional
one (using arrays).  Lists of lists turn up often, though, and we can see how
to deal with them by taking familiar matrix operations as examples.
<html:em>ML for the Working Programmer</html:em> goes as far as Gaussian elimination,
which presents surprisingly few difficulties.</html:p>
                    <html:p>The transpose of the matrix
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix} a & b & c \\
                           d & e & f\end {smallmatrix}\right )]]></fr:tex>
is
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix}
        a & d     \\
        b & e     \\
        c & f
   \end {smallmatrix}\right )]]></fr:tex>,
which in OCaml corresponds to the following transformation on lists of lists:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {[[a; b; c]; [d; e; f]]} \Rightarrow & \text { [[a; d]; [b; e]; [c; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>The workings of function <html:code>transp</html:code> are simple.  If <html:code>rows</html:code> is the
matrix to be transposed, then <html:code>map hd</html:code> extracts its first column and
<html:code>map tl</html:code> extracts its second column:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {map hd rows} \Rightarrow  & \text { [a; d]}\\
\text {map tl rows} \Rightarrow  & \text { [[b; c]; [e; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>A recursive call transposes the latter matrix, which is then given the column
<html:code>[a; d]</html:code> as its first row.
The two functions expressed using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> would otherwise have to be declared
separately.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/</fr:uri>
                    <fr:display-uri>focs-head-tail</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-head-tail/</fr:route>
                    <fr:title text="Getting at the Head and Tail">Getting at the Head and Tail</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let null = function
    | [] -> true
    | x :: l -> false
val null : 'a list -> bool = <fun>
# null []
- : bool = true
# null [1; 2; 3]
- : bool = false
# let hd (x::l) = x
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val hd : 'a list -> 'a = <fun>
# hd [1; 2; 3]
- : int = 1
# let tl (x::l) = l
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val tl : 'a list -> 'a list = <fun>
# tl [7; 6; 5]
- : int list = [6; 5]]]></html:pre>
                    <html:p>The empty list has neither head nor tail.  Applying <html:code>hd</html:code> or <html:code>tl</html:code> to <html:code>[]</html:code>
is an error—strictly speaking, an <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">“exception”</fr:link>.  The function <html:code>null</html:code> can
be used to check for the empty list beforehand.  Taking a list apart using
combinations of <html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right.  Fortunately, it is seldom
necessary because of <html:em>pattern-matching</html:em>.</html:p>
                    <html:p>The declaration of <html:code>null</html:code> introduces a new concept known as "pattern matching",
which we will explore more in subsequent lectures. For now, it is sufficient
to observe that <html:code>let null = function</html:code> allows for matching on the two possible values
that might be passed in as argument to <html:code>null</html:code> here: one for the empty list (for which it returns <html:code>true</html:code>)
and one for non-empty lists (for which it returns <html:code>false</html:code>).</html:p>
                    <html:p>The declaration of <html:code>hd</html:code> above has only one clause, for non-empty lists.  They
have the form <html:code>x::l</html:code> and the function returns <html:code>x</html:code>, which is the head.  If you
compile this program, OCaml also prints a warning to tell us that calling
the function could raise an exception because not all possible inputs are handled,
including a counter-example (in this case, the empty list <html:code>[]</html:code>). The declaration of <html:code>tl</html:code> is similar to <html:code>hd</html:code>.</html:p>
                    <html:p>These three primitive functions are <html:em>polymorphic</html:em> and allow flexibility in the
types of their arguments and results. Note their types!</html:p>
                    <html:pre><![CDATA[# null
- : 'a list -> bool = <fun>
# hd
- : 'a list -> 'a = <fun>
# tl
- : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type variables</html:em> and stand for any types. Code
written using these functions is checked for type correctness at compile time.
And this guarantees strong properties at run time, for example that the
elements of any list all have the same type.  They are usually read as their
corresponding greek characters; <html:code>'a</html:code> is "alpha", <html:code>'b</html:code> is "beta", and so on.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/</fr:uri>
                    <fr:display-uri>focs-insertion-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-insertion-sort/</fr:route>
                    <fr:title text="Insertion Sort">Insertion Sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An insert operation does <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> comparisons on average.</html:p>
                    <html:pre><![CDATA[# let rec ins x = function
    | [] -> [x]
    | y::ys -> if x <= y then x :: y :: ys
               else y :: ins x ys
val ins : 'a -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Insertion sort</html:em> takes <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons on average:</html:p>
                    <html:pre><![CDATA[let rec insort = function
    | [] -> []
    | x::xs -> ins x (insort xs)]]></html:pre>
                    <html:p>Items from the input are copied one at a time to the output.  Each new item is
inserted into the right place so that the output is always in order.</html:p>
                    <html:p>We could easily write <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> versions of these functions, but to no purpose.
Insertion sort is slow because it does <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons (and a lot of list
copying), not because it is recursive.  Its quadratic runtime makes it nearly
useless: it takes 174 seconds for our example while the next-worst figure is
1.4 seconds.</html:p>
                    <html:p>Insertion sort is worth considering because it is easy to code and illustrates
the concepts.  Two efficient sorting algorithms, <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link> and heapsort, can be
regarded as refinements of insertion sort.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/</fr:uri>
                    <fr:display-uri>focs-while</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-while/</fr:route>
                    <fr:title text="Iteration: the while command">Iteration: the while command</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let tlopt = function
  | [] -> None
  | _::xs -> Some xs
val tlopt : 'a list -> 'a list option = <fun>
# let length xs =
    let lp  = ref xs in (* list of uncounted elements *)
    let np  = ref 0  in (* accumulated count *)
    let fin = ref false in
    while not !fin do
      match tlopt !lp with
      | None -> fin := true
      | Some xs ->
          lp := xs;
          np := 1 + !np
    done;
    !np (* the final count is returned *)
val length : 'a list -> int = <fun>]]></html:pre>
                    <html:p>Once we can change the state, we need to do so repeatedly.  <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">Recursion</fr:link> can
serve this purpose, but having to declare a procedure for every loop is
clumsy, and compilers for conventional languages seldom exploit
<fr:link href="/~avsm2/fcs/focs-recursion-vs-iteration/" title="Recursion vs Iteration" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/" display-uri="focs-recursion-vs-iteration" type="local">tail-recursion</fr:link>.</html:p>
                    <html:p>Early programming languages provided little support for repetition.  The
programmer had to set up loops using goto commands, exiting the loop using
another goto controlled by an <html:code>if</html:code>.  Modern languages provide a
confusing jumble of looping constructs, the most fundamental of which is
<html:code>while B do C</html:code>.  The boolean expression <fr:tex display="inline"><![CDATA[B]]></fr:tex> is evaluated,
and if true, command <fr:tex display="inline"><![CDATA[C]]></fr:tex> is executed and the command repeats.  If <fr:tex display="inline"><![CDATA[B]]></fr:tex>
evaluates to false then the <html:code>while</html:code> command terminates, perhaps without
executing <fr:tex display="inline"><![CDATA[C]]></fr:tex> even once.</html:p>
                    <html:p>OCaml’s main looping construct is <html:code>while</html:code>, which returns the value <html:code>()</html:code>.  The
function <html:code>length</html:code> declares <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> to hold the list under
examination (<html:code>lp</html:code>) and number of elements counted so far (<html:code>np</html:code>) as well
as whether the end of the list has been reached (the boolean reference <html:code>fin</html:code>).
While the list is non-empty, we skip over one more element (by setting it to
its tail) and count that element.</html:p>
                    <html:p>The body of the <html:code>while</html:code> loop first checks to see if the end of the list has
been reached, in which case it sets the <html:code>fin</html:code> variable to true.  If there is a
tail value, then two assignments are executed in sequence.  The <html:code>lp</html:code> reference
is set to the tail of the list, and the <html:code>np</html:code> reference integer is incremented
by one.  When the while loop terminates due to the <html:code>fin</html:code> variable being set to
true, the expression <html:code>!np</html:code> returns the computed length as the function’s
result.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-append/</fr:uri>
                    <fr:display-uri>focs-seq-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-append/</fr:route>
                    <fr:title text="Joining Two Sequences">Joining Two Sequences</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec appendq xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons(x, fun () -> appendq (xf ()) yq)
val appendq : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>A more fair alternative:</html:p>
                    <html:pre><![CDATA[# let rec interleave xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons (x, fun () -> interleave yq (xf ()))
val interleave : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>Most list functions and <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> have analogues on sequences, but strange
things can happen.  Can an infinite list be reversed?</html:p>
                    <html:p>Function <html:code>appendq</html:code> is precisely the same idea as <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>
from the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">Lists lecture</fr:link>; it concatenates two sequences.  If the first
argument is infinite, then <html:code>appendq</html:code> never gets to its second argument,
which is lost.  Concatenation of infinite sequences is not terribly
interesting.</html:p>
                    <html:p>The function <html:code>interleave</html:code> avoids this problem by exchanging the two
arguments in each recursive call.  It combines the two <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, losing no
elements.  Interleaving is the right way to combine two potentially infinite
information sources into one.</html:p>
                    <html:p>In both function declarations, observe that each <html:code>xf ()</html:code> is enclosed
within a <fr:tex display="inline"><![CDATA[{\tt  fun () \rightarrow  \ldots }]]></fr:tex>.  Each <html:em>force</html:em> is enclosed within a
<html:em>delay</html:em>.  This practice makes the functions lazy.  A force not enclosed
in a delay, as in <fr:link href="/~avsm2/fcs/focs-seq-consume/" title="Consuming a Sequence" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/" display-uri="focs-seq-consume" type="local"><html:code>get</html:code></fr:link> above, runs the risk of evaluating the sequence
in full.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/</fr:uri>
                    <fr:display-uri>focs-lazy-lists</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-lazy-lists/</fr:route>
                    <fr:title text="Lazy Lists (or Streams)">Lazy Lists (or Streams)</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Lists of possibly <html:em>infinite</html:em> length</html:li>
  <html:li>Elements <html:em>computed upon demand</html:em></html:li>
  <html:li><html:em>Avoids waste</html:em> if there are many solutions</html:li>
  <html:li><html:em>Infinite</html:em> values are a useful abstraction</html:li></html:ul>
                    <html:p>In OCaml, we can implement laziness by <html:em>delaying evaluation</html:em> of the tail of
the list.</html:p>
                    <html:p>Lazy lists have practical uses.  Some algorithms, like <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>, can
yield many solutions when only a few are required.  Sometimes the original
problem concerns infinite series: with lazy lists, we can pretend they really
exist!</html:p>
                    <html:p>We are now dealing with <html:em>infinite</html:em> (or at least unbounded) computations.
A potentially infinite source of data is processed one element at a time, upon
demand.  Such programs are harder to understand than terminating ones and have
more ways of going wrong.</html:p>
                    <html:p>Some purely functional languages, such as Haskell, use lazy evaluation
everywhere.  Even the if-then-else construct can be a function, and all lists
are lazy.  In OCaml, we can declare a type of lists such that evaluation of the
tail does not occur until demanded.  <html:em>Delayed</html:em> evaluation is weaker than
<html:em>lazy</html:em> evaluation, but it is good enough for our purposes and often the
best compromise for performance and memory usage.</html:p>
                    <html:p>The traditional word “stream” is reserved in OCaml parlance for
input/output channels.  Let us call lazy lists <html:em>sequences</html:em> instead.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/</fr:uri>
                    <fr:display-uri>focs-def-lazy-list</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-lazy-list/</fr:route>
                    <fr:title text="Lazy list">Lazy list</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A lazy list is a list of possibly <html:em>infinite</html:em> length whose elements are
<html:em>computed upon demand</html:em>; in OCaml we implement laziness by <html:em>delaying
evaluation</html:em> of the tail of the list. The traditional word “stream” is reserved in
OCaml parlance for input/output channels, so we call lazy lists <html:em>sequences</html:em>
instead.
Introduced in <fr:link href="/~avsm2/fcs/focs-lazy-lists/" title="Lazy Lists (or Streams)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/" display-uri="focs-lazy-lists" type="local">Lazy Lists</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/</fr:uri>
                    <fr:display-uri>focs-linear-search</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-linear-search/</fr:route>
                    <fr:title text="Linear Search">Linear Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>find <fr:tex display="inline"><![CDATA[x]]></fr:tex> in list <fr:tex display="inline"><![CDATA[[x_1,\ldots ,x_n]]]></fr:tex> by comparing with each element</html:li>
  <html:li>obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time</html:li>
  <html:li>simple &amp; general</html:li>
  <html:li>ordered searching needs only <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:li>
  <html:li>indexed lookup needs only <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p><html:em>Linear search</html:em> is the obvious way to find a desired item in a
collection: simply look through all the items, one at a time.  If <fr:tex display="inline"><![CDATA[x]]></fr:tex> is in
the list, then it will be found in <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> steps on average, and even the worst
case is obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                    <html:p>Large collections of data are usually ordered or indexed so that items can be
found in <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> time, which is exponentially better than <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Even
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is achievable (using a hash table), though subject to the usual
proviso that machine limits are not exceeded.</html:p>
                    <html:p>Efficient indexing methods are of prime importance: consider Web
search engines.  Nevertheless, linear search is often used to search small
collections because it is so simple and general, and it is the starting point
for better algorithms.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/</fr:uri>
                    <fr:display-uri>focs-predicate-functionals</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-functionals/</fr:route>
                    <fr:title text="List Functionals for Predicates">List Functionals for Predicates</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec exists p = function
  | [] -> false
  | x::xs -> (p x) || (exists p xs)
val exists : ('a -> bool) -> 'a list -> bool = <fun>
# let rec filter p = function
  | [] -> []
  | x::xs ->
      if p x then
        x :: filter p xs
      else
        filter p xs
val filter : ('a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>A <html:em>predicate</html:em> is a <html:em>boolean-valued</html:em> function.</html:p>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>exists</html:code> transforms a predicate into a predicate over
lists.  Given a list, <html:code>exists p</html:code> tests whether or not some list element
satisfies <html:code>p</html:code> (making it return <html:code>true</html:code>).  If it finds one, it stops
searching immediately, thanks to the behaviour of the lazy <html:code>||</html:code> operator.</html:p>
                    <html:p>Dually, we have a functional to test whether all list elements satisfy the
predicate.  If it finds a counterexample then it, too, stops searching.</html:p>
                    <html:pre><![CDATA[# let rec all p = function
  | [] -> true
  | x::xs -> (p x) && all p xs
val all : ('a -> bool) -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The <html:code>filter</html:code> functional, like <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>, transforms lists.  It applies a
predicate to all the list elements, but instead of returning the
resulting values (which could only be <html:code>true</html:code> or <html:code>false</html:code>), it returns
the list of elements satisfying the predicate.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/</fr:uri>
                    <fr:display-uri>focs-take-drop</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-take-drop/</fr:route>
                    <fr:title text="List Utilities: take and drop">List Utilities: take and drop</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>This lecture examines more list utilities, illustrating more patterns of
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, and concludes with a small program for <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.</html:p>
                    <html:p>The functions <html:code>take</html:code> and <html:code>drop</html:code> divide a list
into parts, returning or discarding the first <fr:tex display="inline"><![CDATA[i]]></fr:tex> elements.</html:p>
                    <fr:tex display="block"><![CDATA[xs = [\underbrace {x_0,\ldots ,x_{i-1}}_{\text {take i xs}},
      \underbrace {x_i,\ldots ,x_{n-1}}_{\text {drop i xs}} ]]]></fr:tex>
                    <html:p>They can be implemented in OCaml as follows:</html:p>
                    <html:pre><![CDATA[# let rec take i = function
    | [] -> []
    | x::xs ->
        if i > 0 then x :: take (i - 1) xs
        else []
val take : int -> 'a list -> 'a list = <fun>
# let rec drop i = function
    | [] -> []
    | x::xs ->
        if i > 0 then drop (i-1) xs
        else x::xs
val drop : int -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Applications of <html:code>take</html:code> and <html:code>drop</html:code> will appear in future lectures.  Typically,
they divide a collection of items into equal parts for recursive processing.</html:p>
                    <html:p>The <html:code>take</html:code> function is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>, but making it so would not improve
its efficiency.  The task requires copying up to <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements, which must
take <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> space and time.</html:p>
                    <html:p>Function <html:code>drop</html:code> simply skips over <fr:tex display="inline"><![CDATA[i]]></fr:tex> list elements.  This requires
<fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time but only constant space.  It is iterative and much faster than
<html:code>take</html:code>.  Both functions use <fr:tex display="inline"><![CDATA[O(i)]]></fr:tex> time, but skipping elements is faster
than copying them:  <html:code>drop</html:code>’s constant factor is smaller.</html:p>
                    <html:p>Both functions take an integer and a list, returning a list of the same type.
So their type is <html:code>int -&gt; 'a list -&gt; 'a list</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-strings-chars/</fr:uri>
                    <fr:display-uri>focs-strings-chars</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-strings-chars/</fr:route>
                    <fr:title text="Lists, Strings and Characters">Lists, Strings and Characters</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Strings are provided in most programming languages to allow text processing.
Strings are essential for communication with users. Even a purely numerical
program formats its results ultimately as strings.</html:p>
                    <html:pre><![CDATA[# 'a'   (* a character constant *)
- : char = 'a'
# "a"   (* a string constant of length 1 *)
- : string = "a"
# "abc" (* a string constant of length 3 *)
- : string = "abc"
# String.length "abc"
- : int = 3
# "abc" ^ "def"  (* concatenate two strings *)
- : string = "abcdef"]]></html:pre>
                    <html:p>In a few programming languages, strings simply are lists of characters. In
OCaml they are a separate type, unrelated to lists, reflecting the fact that
strings are an abstract concept in themselves.</html:p>
                    <html:p>Similarly, characters are not strings of size one, but are a primitive concept.
Character constants in OCaml have the form <html:code>'c'</html:code>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is any character.
For example, the comma character is <html:code>','</html:code>.</html:p>
                    <html:p>Special characters are coded in strings using <html:em>escape sequences</html:em> involving the
backslash character; among many others, a double quote is written <html:code><![CDATA["\\"]]></html:code> and
the newline character is written <html:code><![CDATA["\n"]]></html:code>. For example, the string
<html:code><![CDATA["I\nLIKE\nCHEESE\n"]]></html:code> represents three text lines.</html:p>
                    <html:p>In addition to the operators described above, the relations <html:code>&lt;</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code>, and
<html:code>&gt;=</html:code> work for strings and yield alphabetic order (more precisely, lexicographic
order with respect to ASCII character codes).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matmul-ocaml/</fr:uri>
                    <fr:display-uri>focs-matmul-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-matmul-ocaml/</fr:route>
                    <fr:title text="Matrix Multiplication in OCaml">Matrix Multiplication in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:em>Dot product</html:em> of two vectors—a <html:em><fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link></html:em></html:p>
                    <html:pre><![CDATA[# let rec dotprod xs ys =
    match xs, ys with
    | [], [] -> 0.0
    | x::xs, y::ys ->  (x *. y) +. (dotprod xs ys)
Lines 2-4, characters 5-51:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
([], _::_)
val dotprod : float list -> float list -> float = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Matrix product</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let rec matprod arows brows =
    let cols = transp brows in
    map (fun row -> map (dotprod row) cols) arows
val matprod : float list list -> float list list -> float list list = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local"><html:code>transp brows</html:code></fr:link> converts <fr:tex display="inline"><![CDATA[B]]></fr:tex> into a list of columns, yielding a
list whose elements are the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Each row of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is
obtained by multiplying a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex> by the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
                    <html:p>Because <html:code>dotprod</html:code> is curried, it can be applied to a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The
resulting function is applied to all the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  We have another
example of currying and partial application.</html:p>
                    <html:p>The outer <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> applies <html:code>dotprod</html:code> to each row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The inner
<html:code>map</html:code>, using <html:code>fun</html:code>-notation, applies <html:code>dotprod row</html:code> to each
column of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Compare with the version in <html:em>ML for the Working
  Programmer</html:em> (page 89) which does not use <html:code>map</html:code> and requires two
additional function declarations.</html:p>
                    <html:p>In the dot product function, the two vectors must have the same length.
Otherwise, <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Match_failure</html:code> is raised.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge/</fr:uri>
                    <fr:display-uri>focs-merge</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge/</fr:route>
                    <fr:title text="Merging Two Lists">Merging Two Lists</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Merge joins two sorted lists.</html:p>
                    <html:pre><![CDATA[# let rec merge = function
    | [], ys -> ys
    | xs, [] -> xs
    | x::xs, y::ys ->
        if x <= y then
          x :: merge (xs, y::ys)
        else
          y :: merge (x::xs, ys)
val merge : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Generalises <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insert</fr:link> to two lists, and does at most <fr:tex display="inline"><![CDATA[m+n-1]]></fr:tex> comparisons.</html:p>
                    <html:p><html:em>Merging</html:em> means combining two sorted lists to form a larger sorted list.
It does at most <fr:tex display="inline"><![CDATA[m+n]]></fr:tex> comparisons, where <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are the lengths of the
input lists.  If <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are roughly equal then we have a fast way of
constructing sorted lists; if <fr:tex display="inline"><![CDATA[n=1]]></fr:tex> then merging degenerates to insertion,
doing much work for little gain.</html:p>
                    <html:p>Merging is the basis of several sorting algorithms; we look at a
divide-and-conquer one.  Mergesort is seldom found in conventional programming
because it is hard to code for arrays; it works nicely with lists.  It divides
the input (if non-trivial) into two roughly equal parts, sorts them
recursively, then merges them.</html:p>
                    <html:p>Function <html:code>merge</html:code> is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>; the recursion is deep.  An iterative
version is of little benefit for the same reasons that apply to
<fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link> in the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">earlier lecture on Lists</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/</fr:uri>
                    <fr:display-uri>focs-def-polymorphism</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-polymorphism/</fr:route>
                    <fr:title text="Polymorphism">Polymorphism</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A polymorphic function allows flexibility in the types of its arguments and
results: the list primitives <html:code>null</html:code>, <html:code>hd</html:code> and <html:code>tl</html:code> work whatever
the element type is. Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type
variables</html:em> and stand for any types, and code written using them is still checked
for type correctness at compile time.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/</fr:uri>
                    <fr:display-uri>focs-quicksort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort/</fr:route>
                    <fr:title text="Quicksort: The Code">Quicksort: The Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quick = function
    | [] -> []
    | [x] -> [x]
    | a::bs ->
        let rec part l r = function
          | [] -> (quick l) @ (a :: quick r)
          | x::xs ->
              if (x <= a) then
                part (x::l) r xs
              else
                part l (x::r) xs
        in
        part [] [] bs
val quick : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Our OCaml quicksort copies the items.  It is still pretty fast, and it is much
easier to understand.  It takes roughly 0.74 seconds to sort our list of random
numbers.</html:p>
                    <html:p>The function declaration consists of three clauses.  The first handles the
empty list; the second handles singleton lists (those of the form <html:code>[x]</html:code>); the
third handles lists of two or more elements.  Often, lists of length up to five
or so are treated as special cases to boost speed.</html:p>
                    <html:p>The locally declared function <html:code>part</html:code> partitions the input using <html:code>a</html:code> as the
pivot.  The arguments <html:code>l</html:code> and <html:code>r</html:code> accumulate items for the left (<fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>) and
right (<fr:tex display="inline"><![CDATA[>a]]></fr:tex>) parts of the input, respectively.</html:p>
                    <html:p>It is not hard to prove that quicksort does <fr:tex display="inline"><![CDATA[n\log  n]]></fr:tex> comparisons, <html:em>in the average case</html:em>
(see <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">page 94 of Aho</fr:link>).  With random data, the pivot
usually has an average value that divides the input in two approximately equal
parts.  We have the recurrence <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>, which is
<fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.  In our example, it is about 235 times faster than <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insertion
sort</fr:link>.</html:p>
                    <html:p>In the worst case, quicksort's running time is quadratic!  An example is when
its input is almost sorted or reverse sorted.  Nearly all of the items end up
in one partition; work is not divided evenly.  We have the recurrence
<fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>, which is <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Randomising the input
makes the worst case highly unlikely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/</fr:uri>
                    <fr:display-uri>focs-rev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-rev/</fr:route>
                    <fr:title text="Reversing a List in O(n)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec rev_app xs ys =
    match xs, ys with
    | [], ys    -> ys
    | x::xs, ys -> rev_app xs (x::ys)
val rev_app : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {rev\_app }[a; b; c]\;[] \Rightarrow  &\; \text {rev\_app }[b; c]\; [a] \\
  \Rightarrow  &\; \text {rev\_app }[c]\; [b; a] \\
  \Rightarrow  &\; \text {rev\_app }[]\; [c; b; a] \\
  \Rightarrow  &\; [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>Calling <html:code>rev_app xs ys</html:code> reverses the elements of <html:code>xs</html:code> and
prepends them to <html:code>ys</html:code>.  Now we may declare</html:p>
                    <html:pre><![CDATA[# let rev xs = rev_app xs []
val rev : 'a list -> 'a list = <fun>
# rev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <html:p>It is easy to see that this reverse function performs just <fr:tex display="inline"><![CDATA[n]]></fr:tex> conses, given
an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element list.  For both reverse functions, we could count the number of
conses precisely—not just up to a constant factor.  <fr:link href="/~avsm2/fcs/focs-o-notation/" title="Comparing Algorithms: O Notation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-o-notation/" display-uri="focs-o-notation" type="local"><fr:tex display="inline"><![CDATA[O]]></fr:tex> notation</fr:link> is still
useful to describe the overall running time: the time taken by a cons
varies from one system to another.</html:p>
                    <html:p>The accumulator <fr:tex display="inline"><![CDATA[y]]></fr:tex> makes the function <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>.  But the gain in complexity
arises from the removal of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.  Replacing an expensive operation (append)
by a series of cheap operations (cons) is called <html:em>reduction in strength</html:em>
and is a common technique in computer science.  It originated when many
computers did not have a hardware multiply instruction; the series of products
<fr:tex display="inline"><![CDATA[i\times  r]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, <fr:tex display="inline"><![CDATA[\ldots , n]]></fr:tex> could more efficiently be computed by
repeated addition.  Reduction in strength can be done in various ways; we
shall see many instances of removing append.</html:p>
                    <html:p>Consing to an accumulator produces the result in reverse.  If
that forces the use of an extra list reversal then the iterative function
may be much slower than the recursive one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-nrev/</fr:uri>
                    <fr:display-uri>focs-nrev</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-nrev/</fr:route>
                    <fr:title text="Reversing a List in O(n^2)">Reversing a List in <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex></fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Let us consider one way to reverse a list.</html:p>
                    <html:pre><![CDATA[# let rec nrev = function
  | [] -> []
  | x::xs -> (nrev xs) @ [x]
val nrev : 'a list -> 'a list = <fun>
# nrev [1; 2; 3]
- : int list = [3; 2; 1]]]></html:pre>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {nrev }[a; b; c] \Rightarrow  &\; \text {nrev }[b; c]\;@\;[a] \\
  \Rightarrow  &\;  (\text {nrev }[c]\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  ((\text {nrev }[]\;@\;[c])\;@\;[b])\;@\;[a] \\
  \Rightarrow  &\;  (([]\;@\;[c])\;@\;[b])\;@\;[a] \ \ldots  \ [c; b; a]
\end {aligned}
]]></fr:tex>
                    <html:p>This reverse function is grossly inefficient due to poor usage of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>, which
copies its first argument.  If <html:code>nrev</html:code> is given a list of length <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>, then
append makes <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> conses to copy the reversed tail.  Constructing the list
<html:code>[x]</html:code> calls <html:code>cons</html:code> again, for a total of <fr:tex display="inline"><![CDATA[n]]></fr:tex> calls.  Reversing the tail
requires <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> more conses, and so forth.  The total number of conses is:</html:p>
                    <fr:tex display="block"><![CDATA[ 0 + 1 + 2 + \cdots  + n = {n(n+1)/2} ]]></fr:tex>
                    <html:p>The time complexity is therefore <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Space complexity is only <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>
because the copies don’t all exist at the same time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-curry-shorthand/</fr:uri>
                    <fr:display-uri>focs-curry-shorthand</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-curry-shorthand/</fr:route>
                    <fr:title text="Shorthand for Curried Functions">Shorthand for Curried Functions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A function-returning function is just a function of two arguments.</html:p>
                    <html:p>This <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link> syntax is nicer than nested <html:code>fun</html:code> binders:</html:p>
                    <html:pre><![CDATA[# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>
# let dub = prefix "Sir "
val dub : string -> string = <fun>]]></html:pre>
                    <html:p>Curried functions allows <html:em>partial application</html:em> (to the first argument).</html:p>
                    <html:p>In OCaml, an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-argument curried function <html:code>f</html:code> can be declared using the syntax:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  let \; f \; x_1 \: \ldots  \: x_{n} \: = \: E]]></fr:tex>
                    <html:p>and applied using the syntax:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  \; E_1 \; \ldots  \; E_n]]></fr:tex>
                    <html:p>If <html:code>f</html:code> is not recursive, then it is equivalent to the function expressed via nesting as follows:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  fun \; x_1 \; \rightarrow  \cdots  \rightarrow  fun \; x_{n} \rightarrow  E ]]></fr:tex>
                    <html:p>We now have two ways of expressing functions of multiple arguments: either by
passing a pair of arguments or by currying.  Currying allows <html:em>partial application</html:em>
which is useful when fixing the first argument yields a function
that is interesting in its own right.  An example from mathematics is the
function <fr:tex display="inline"><![CDATA[x^y]]></fr:tex>, where fixing <fr:tex display="inline"><![CDATA[y=2]]></fr:tex> yields a function in <fr:tex display="inline"><![CDATA[x]]></fr:tex> alone, namely
squaring. Similarly, <fr:tex display="inline"><![CDATA[y=3]]></fr:tex> yields cubing, while <fr:tex display="inline"><![CDATA[y=1]]></fr:tex> yields the identity
function.</html:p>
                    <html:p>Though the function <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> (which returns the head of a list) is not
curried, it may be used with the curried application syntax in some
expressions:</html:p>
                    <html:pre><![CDATA[# List.hd [dub; promote] "Hamilton"
- : string = "Sir Hamilton"]]></html:pre>
                    <html:p>Here <html:code>List.hd</html:code> is applied to a list of functions, and the resulting function
<html:code>dub</html:code> is then applied to the string <html:code>"Hamilton"</html:code>.  The idea of
executing code stored in data structures reaches its full development in
<html:em>object-oriented</html:em> programming, like in Java.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/</fr:uri>
                    <fr:display-uri>focs-list-primitives</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-list-primitives/</fr:route>
                    <fr:title text="The List Primitives">The List Primitives</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>There are two kinds of lists:</html:p>
                    <html:ul><html:li><html:code>[]</html:code> represents the empty list</html:li>
  <html:li><html:code>x :: l</html:code> is the list with head <fr:tex display="inline"><![CDATA[x]]></fr:tex> and tail <fr:tex display="inline"><![CDATA[l]]></fr:tex></html:li></html:ul>
                    <html:pre><![CDATA[# let nil = []
val nil : 'a list = []
# 1 :: nil
- : int list = [1]
# 1 :: 2 :: nil
- : int list = [1; 2]]]></html:pre>
                    <html:p>The operator <html:code>::</html:code> (also called <html:code>List.cons</html:code> for “construct”), puts a new element on
to the head of an existing list.  While we should not be too preoccupied with
implementation details, it is essential to know that <html:code>::</html:code> is an <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
operation.  It uses constant time and space, regardless of the length of the
resulting list.  Lists are represented internally with a linked structure;
adding a new element to a list merely hooks the new element to the front of
the existing structure.  Moreover, that structure continues to denote the same
list as it did before; to see the new list, one must look at the new <html:code>::</html:code> node
(or “cons cell”) just created.  We will explain the <html:code>'a</html:code> notation in the next
section.</html:p>
                    <html:p>Here we see the element <html:code>1</html:code> being consed to the front of the list <html:code>[3; 5; 9]</html:code>:</html:p>
                    <fr:tex display="block"><![CDATA[\begin{array}{ccccccccccc}
:: & \to & \cdots & :: & \to &  :: & \to &  :: & \to & [] \\
\downarrow &  &        & \downarrow &  & \downarrow &  & \downarrow  \\
1     &  &        & 3     &  & 5     &  & 9
\end{array}]]></fr:tex>
                    <html:p>Given a list, taking its first element (its “head”) or its list of
remaining elements (its “tail”) also takes constant time.  Each
operation just follows a link.  In the diagram above, the first down arrow
leads to the head and the leftmost right arrow leads to the tail.  Once we
have the tail, its head is the second element of the original list, etc.</html:p>
                    <html:p>The tail is <html:em>not</html:em> the last element; it is the <html:em>list</html:em> of all elements
other than the head!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/</fr:uri>
                    <fr:display-uri>focs-merge-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge-sort/</fr:route>
                    <fr:title text="Top-down Merge sort">Top-down Merge sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec tmergesort = function
    | [] -> []
    | [x] -> [x]
    | xs ->
        let k = List.length xs / 2 in
        let l = tmergesort (take k xs) in
        let r = tmergesort (drop k xs) in
        merge (l, r)
val tmergesort : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons in worst case</html:p>
                    <html:p>Mergesort’s <html:em>divide</html:em> stage divides the input not by choosing a pivot (as
in <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>) but by simply counting out half of the elements.  The
<html:em>conquer</html:em> stage again involves recursive calls, and the <html:em>combine</html:em>
stage involves merging.  Function <html:code>tmergesort</html:code> takes roughly 1.4
seconds to sort the list <html:code>rs</html:code>.</html:p>
                    <html:p>In the worst case, mergesort does <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons, with the same
recurrence equation as in quicksort’s average case.  Because <fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>take</html:code></fr:link> and
<fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>drop</html:code></fr:link> divide the input in two equal parts (they differ at most by
one element), we always have <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>.</html:p>
                    <html:p>Quicksort is nearly 3 times as fast in the example.  But it risks a
quadratic worst case!  Merge sort is safe but slow.  So which algorithm is
best?</html:p>
                    <html:p>We have seen a <html:em>top-down</html:em> mergesort.  <html:em>Bottom-up</html:em> algorithms also
exist.  They start with a list of one-element lists and repeatedly merge
adjacent lists until only one is left.  A refinement, which exploits any
initial order among the input, is to start with a list of increasing or
decreasing runs of input items.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/</fr:uri>
                    <fr:display-uri>focs-map</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-map/</fr:route>
                    <fr:title text="map: the “Apply to All” Function">map: the “Apply to All” Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec map f = function
    | [] -> []
    | x::xs -> (f x) :: map f xs
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
# map (fun s -> s ^ "ppy") ["Hi"; "Ho"]
- : string list = ["Hippy"; "Hoppy"]
# map (map double) [[1]; [2; 3]]
- : int list list = [[2]; [4; 6]]]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>map</html:code> applies a function to every element of a list,
returning a list of the function’s results.  “Apply to all” is a fundamental
operation and we shall see several applications of it below.  We
again see the advantages of <html:code>fun</html:code>-notation, <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">currying</fr:link> and
<html:code>map</html:code>.  If we did not have them, the first use of <html:code>map</html:code> in the above code block
would require a preliminary function declaration:</html:p>
                    <html:pre><![CDATA[# let rec sillylist = function
    | [] -> []
    | s::ss -> (s ^ "ppy") :: sillylist ss
val sillylist : string list -> string list = <fun>]]></html:pre>
                    <html:p>An expression containing several applications of functionals—such as our
second example—can abbreviate a long series of declarations.  Sometimes this
coding style is cryptic, but it can be clear as crystal.  Treating functions
as values lets us capture common program structures once and for all.</html:p>
                    <html:p>In the second example, <fr:link href="/~avsm2/fcs/focs-anonymous-functions/" title="Functions Without Names" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/" display-uri="focs-anonymous-functions" type="local"><html:code>double</html:code></fr:link> is the obvious integer doubling function we
defined earlier.  Note that <html:code>map</html:code> is a built-in OCaml function in the
form of <html:code>List.map</html:code>.  OCaml’s standard library includes, among much else, many
list functions.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-3/</fr:uri>
                    <fr:display-uri>focs-ex-4-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-3/</fr:route>
                    <fr:title text="Exercises › A non-exhaustive zip"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › A non-exhaustive zip</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>How does this version of <html:code>zip</html:code> differ from <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local">the one above</fr:link>?</html:p>
                    <html:pre><![CDATA[let rec zip xs ys =
  match xs, ys with
  | (x::xs, y::ys) -> (x, y) :: zip xs ys
  | ([], [])   -> []]]></html:pre>
                    <html:pre><![CDATA[Lines 2-4, characters 5-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(_::_, [])]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-5/</fr:uri>
                    <fr:display-uri>focs-ex-9-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-5/</fr:route>
                    <fr:title text="Exercises › All lists of zeroes and ones"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › All lists of zeroes and ones</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code the lazy list whose elements are all ordinary lists of zeroes and ones, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 1]; [1; 0]; [1; 1]; [0; 0; 0]; </html:code>….  (Taken from the exam question
2003 Paper 1 Question 5.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-4/</fr:uri>
                    <fr:display-uri>focs-ex-4-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-4/</fr:route>
                    <fr:title text="Exercises › Assumptions in making change"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Assumptions in making change</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>What assumptions do the <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">‘making change’</fr:link> functions make about the variables <html:code>till</html:code> and <html:code>amt</html:code>?
Describe what could happen if these assumptions were violated.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-2/</fr:uri>
                    <fr:display-uri>focs-ex-9-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-2/</fr:route>
                    <fr:title text="Exercises › Concatenating infinite sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Concatenating infinite sequences</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider the list function <html:code>concat</html:code>, which concatenates a list of lists to form a single list. Can
it be generalised to concatenate a sequence of sequences? What can go wrong?</html:p>
                    <html:pre><![CDATA[let rec concat = function
| [] -> []
| l::ls -> l @ concat ls]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-6/</fr:uri>
                    <fr:display-uri>focs-ex-9-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-6/</fr:route>
                    <fr:title text="Exercises › Enumerating palindromes"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Enumerating palindromes</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>(Continuing the previous exercise.)
A <html:em>palindrome</html:em> is a list that equals its own reverse. Code the lazy list whose elements are all
palindromes of 0s and 1s, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 0; 0]; [0; 1; 0]; [1; 1]; [1; 0; 1]; [1; 1; 1]; [0; 0; 0; 0]; </html:code>, …. You
may take the reversal function <html:code>List.rev</html:code> as given.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-3/</fr:uri>
                    <fr:display-uri>focs-ex-3-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-3/</fr:route>
                    <fr:title text="Exercises › Even-numbered elements"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Even-numbered elements</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to return the list consisting of the even-numbered elements of the list given as its
argument. For example, given <html:code>[a; b; c; d]</html:code> it should return <html:code>[b; d]</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-4/</fr:uri>
                    <fr:display-uri>focs-ex-5-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-4/</fr:route>
                    <fr:title text="Exercises › Implementing bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing bubble sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement bubble sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-2/</fr:uri>
                    <fr:display-uri>focs-ex-5-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-2/</fr:route>
                    <fr:title text="Exercises › Implementing selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing selection sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement selection sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-2/</fr:uri>
                    <fr:display-uri>focs-ex-3-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-2/</fr:route>
                    <fr:title text="Exercises › Last element of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Last element of a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to return the last element of a non-empty list. How efficiently can this be done?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-1/</fr:uri>
                    <fr:display-uri>focs-ex-11-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-1/</fr:route>
                    <fr:title text="Exercises › Lists of references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Lists of references</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Comment, with examples, on the differences between an <html:code>int ref list</html:code> and an <html:code>int list ref</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-3/</fr:uri>
                    <fr:display-uri>focs-ex-9-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-3/</fr:route>
                    <fr:title text="Exercises › Making change lazily"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Making change lazily</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">make change</fr:link> using <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, delivering the sequence of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">all possible ways of
making change</fr:link>. Using sequences allows us to compute solutions one at a time when there exists an
astronomical number. Represent lists of coins using ordinary lists. (<html:em>Hint</html:em>: to  benefit from
laziness you may need to pass around the sequence of alternative solutions as a function of type
<html:code>unit -&gt; (int list) seq</html:code>.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-5/</fr:uri>
                    <fr:display-uri>focs-ex-8-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-5/</fr:route>
                    <fr:title text="Exercises › Making change with map"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Making change with map</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Recall the making change function of <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">More on Lists</fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                    <html:p>Function <html:code>allc</html:code> applies the function ‘cons a <html:code>c</html:code>’ to every element of a list. Eliminate it by
declaring a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried</fr:link> cons function and applying <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-3/</fr:uri>
                    <fr:display-uri>focs-ex-8-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-3/</fr:route>
                    <fr:title text="Exercises › Mapping over lists of lists"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Mapping over lists of lists</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Without using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> write a function <html:code>map2</html:code> such that <html:code>map2 f</html:code> is equivalent to <html:code>map (map f)</html:code>. The
obvious solution requires declaring two recursive functions. Try to get away with only one by
exploiting nested <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-2/</fr:uri>
                    <fr:display-uri>focs-ex-4-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-2/</fr:route>
                    <fr:title text="Exercises › Partitioning integers by sign"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Partitioning integers by sign</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function that takes a list of integers and returns two lists, the first consisting of all
non-negative numbers found in the input and the second consisting of all the negative numbers.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-6/</fr:uri>
                    <fr:display-uri>focs-ex-4-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-6/</fr:route>
                    <fr:title text="Exercises › Reasoning from polymorphic types"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Reasoning from polymorphic types</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We know nothing about the functions <html:code>f</html:code> and <html:code>g</html:code> other than their polymorphic types:
<html:code>val f : 'a * 'b -&gt; 'b * 'a</html:code> and <html:code>val g : 'a -&gt; 'a list</html:code>.
Suppose that <html:code>f (1, true)</html:code> and <html:code>g 0</html:code> are evaluated and return their results. State, with reasons,
what you think the resulting values will be.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-1/</fr:uri>
                    <fr:display-uri>focs-ex-4-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-1/</fr:route>
                    <fr:title text="Exercises › Set union without repetitions"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Set union without repetitions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Sets can be represented in OCaml using lists containing no duplicated items
(i.e. where no item is equal to another using <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link> comparison).</html:p>
                    <html:p>Using the <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link> function defined above, code a function to implement set
union. It should avoid introducing repetitions, for example the union of the
lists <html:code>[4; 7; 1]</html:code> and <html:code>[6; 4; 7]</html:code> should be <html:code>[1; 6; 4; 7]</html:code> (though the order
does not matter).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-1/</fr:uri>
                    <fr:display-uri>focs-ex-3-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-1/</fr:route>
                    <fr:title text="Exercises › Summing a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Summing a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function</fr:link> to compute the sum of a list’s elements. Then code an <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> version
and comment on the improvement in efficiency.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-5/</fr:uri>
                    <fr:display-uri>focs-ex-3-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-5/</fr:route>
                    <fr:title text="Exercises › Tails of a list"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Tails of a list</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function <html:code>tails</html:code> to return the list of the tails of its argument. For example, given
<html:code>[1; 2; 3]</html:code> it should return <html:code>[[1; 2; 3]; [2; 3]; [3]; []]</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-sorting/</fr:uri>
                <fr:display-uri>focs-topic-sorting</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-sorting/</fr:route>
                <fr:title text="Sorting">Sorting</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-append-free/</fr:uri>
                    <fr:display-uri>focs-quicksort-append-free</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort-append-free/</fr:route>
                    <fr:title text="Append-Free Quicksort">Append-Free Quicksort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quik = function
    | ([], sorted) -> sorted
    | ([x], sorted) -> x::sorted
    | a::bs, sorted ->
       let rec part = function
         | l, r, [] -> quik (l, a :: quik (r, sorted))
         | l, r, x::xs ->
             if x <= a then
               part (x::l, r, xs)
             else
               part (l, x::r, xs)
       in
       part ([], [], bs)
val quik : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>The list <html:code>sorted</html:code> accumulates the result in the <html:em>combine</html:em> stage of
the quicksort algorithm.  We have again used the standard technique for
<fr:link href="/~avsm2/fcs/focs-rev/" title="Reversing a List in O(n)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-rev/" display-uri="focs-rev" type="local">eliminating append</fr:link>.  Calling <html:code>quik(xs, sorted)</html:code> reverses the elements of
<html:code>xs</html:code> and prepends them to the list <html:code>sorted</html:code>.</html:p>
                    <html:p>Looking closely at <html:code>part</html:code>, observe that <html:code>quik(r, sorted)</html:code> is
performed first.  Then <html:code>a</html:code> is consed to this sorted list.  Finally,
<html:code>quik</html:code> is called again to sort the elements of <html:code>l</html:code>.</html:p>
                    <html:p>The speedup is significant.  An imperative quicksort coded in Pascal (taken
from <fr:link href="https://algs4.cs.princeton.edu/20sorting/" type="external">Sedgewick</fr:link>) is just slightly faster than function
<html:code>quik</html:code>.  The near-agreement is surprising because the computational overheads
of lists exceed those of arrays.  In realistic applications, comparisons are
the dominant cost and the overheads matter even less.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-bounds/</fr:uri>
                    <fr:display-uri>focs-sorting-bounds</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sorting-bounds/</fr:route>
                    <fr:title text="How Fast Can We Sort?">How Fast Can We Sort?</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>typically count <html:em>comparisons</html:em> <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex></html:li>
  <html:li>there are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements</html:li>
  <html:li>each comparison eliminates <html:em>half</html:em> of the permutations <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex></html:li>
  <html:li>therefore <fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex></html:li></html:ul>
                    <html:p>The usual measure of efficiency for sorting algorithms is the number of
comparison operations required.  <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link> requires only <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>
comparisons to sort an input of <fr:tex display="inline"><![CDATA[n]]></fr:tex> items.  It is straightforward to prove
that this complexity is the best possible.  There
are <fr:tex display="inline"><![CDATA[n!]]></fr:tex> permutations of <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements and each comparison distinguishes two
permutations.  The lower bound on the number of comparisons, <fr:tex display="inline"><![CDATA[C(n)]]></fr:tex>, is
obtained by solving <fr:tex display="inline"><![CDATA[2^{C(n)}\geq  n!]]></fr:tex>; therefore
<fr:tex display="inline"><![CDATA[C(n)\geq  \log (n!)\approx  n\log  n-1.44n]]></fr:tex>.</html:p>
                    <html:p>In order to compare the sorting algorithms, we use the <fr:link href="http://www.firstpr.com.au/dsp/rand31/p1192-park.pdf" type="external">following source</fr:link> of
pseudo-random numbers. Never mind how this works: generating
statistically good random numbers is hard.  Much effort has gone into those few
lines of code.</html:p>
                    <html:pre><![CDATA[# let nextrandom seed =
    let a = 16807.0 in
    let m = 2147483647.0 in
    let t = a *. seed in
    t -. m *. (floor (t /. m))
val nextrandom : float -> float = <fun>
# let rec randlist (seed, seeds) = function
    | 0 -> (seed, seeds)
    | n -> randlist (nextrandom seed, seed::seeds) (n-1)
val randlist : float * float list -> int -> float * float list = <fun>]]></html:pre>
                    <html:p>We can now bind the identifier <html:code>rs</html:code> to a list of 10,000 random numbers.</html:p>
                    <html:pre><![CDATA[# let seed, rs = randlist (1.0, []) 10000
val seed : float = 1043618065.
val rs : float list =
  [1484786315.; 925166085.; 1614852353.; 721631166.; 173942219.; 1229443779.;
   789328014.; 570809709.; 1760109362.; 270600523.; 2108528931.; 16480421.;
   519782231.; 162430624.; 372212905.; 1954184989.; 898872741.; 1651521688.;
   1114791388.; 1325968501.; 1469981427.; 465437343.; 1732504088.;
   280054095.; 1924919450.; 1244369648.; 1524535715.; 706293012.;
   1372325856.; 1302473561.; 941382430.; 2137445578.; 1937168414.;
   1852570660.; 495231255.; 1092873378.; 140232191.; 328129841.; 632752255.;
   227857208.; 1616471915.; 719842438.; 1402481130.; 745001020.; 791471334.;
   2131048000.; 312659966.; 1389551813.; 443838892.; 854190041.; 741774068.;
   267473377.; 1372555293.; 1539748349.; 697860888.; 1261546017.; 734770781.;
   1512111397.; 813238415.; 1034499961.; 602256496.; 462191385.; 250718457.;
   246489360.; 295426232.; 468306241.; 877829533.; 1130589227.; 1914364883.;
   1479854970.; 878528585.; 1268712064.; 115837978.; 1803525169.; 689954646.;
   1174020926.; 651968560.; 391152461.; 1776325865.; 2015344107.; 246977673.;
   1381242649.; 1115030853.; 190703911.; 316761032.; 464218769.; 1537522160.;
   1958981931.; 390463588.; 224009597.; 235243732.; 620352731.; 1374109567.;
   832140633.; 675075162.; 1296171190.; 2009054653.; 1534419747.; 145880482.;
   1649432515.; 403989126.; 1112417244.; 1290575192.; 896661113.; 218545469.;
   1002393512.; 2131316096.; 551979127.; 932010335.; 665881436.; 1975412808.;
   639877791.; 1781707137.; 894518191.; 568004958.; 1331430214.; 629489848.;
   183264178.; 162027282.; 464592882.; 93302056.; 1178713033.; 1401486247.;
   1846150129.; 1646978216.; 1104441491.; 111995009.; 66193165.; 2038880392.;
   79340676.; 871801051.; 967550305.; 2067810758.; 1600354198.; 1746626663.;
   1516388116.; 1308870791.; 173082747.; 189881227.; 478010722.; 739707315.;
   255334803.; 164203714.; 1893097038.; 1587694259.; 292950569.; 918323194.;
   41453146.; 1217297445.; 256768724.; 586494122.; 586258194.; 660494391.;
   507554325.; 699716071.; 672895139.; 76065072.; 1594869218.; 1439459639.;
   641123634.; 1650611940.; 177447368.; 301427463.; 525804524.; 553672425.;
   926899509.; 794676486.; 690277940.; 2115070333.; 1062048650.; 1653192448.;
   1808855340.; 126475289.; 1028198214.; 1739565096.; 1515748830.;
   427491435.; 319330584.; 666483848.; 854842154.; 1853528448.; 1975611245.;
   1905343266.; 1229802342.; 1416055428.; 2091603253.; 1068308139.;
   198239748.; 982076370.; 1094563396.; 44402415.; 889814989.; 290736902.;
   417580014.; 1935788352.; 595665917.; 367638848.; 894945148.; 1868608068.;
   317883051.; 941451621.; 1595942893.; 789094274.; 1150772108.; 422742112.;
   1444245279.; 1273601104.; 256005435.; 1742330161.; 1514599036.;
   956344512.; 2113041793.; 293237373.; 1386995194.; 1509339194.; 891946522.;
   1020832915.; 592544922.; 1746311153.; 1471539715.; 143832370.;
   2041568248.; 1039556199.; 1608726047.; 1205124472.; 2123533995.;
   1560620058.; 1837598795.; 1028172251.; 98318742.; 1405510706.;
   1047695837.; 59221314.; 1822176683.; 1096018886.; 1528104537.;
   1270922857.; 812074106.; 291115596.; 795788616.; 638657646.; 2034314619.;
   1527649272.; 156357479.; 1010056202.; 1139413443.; 1110927723.;
   1216083346.; 846825145.; 2100385733.; 315213605.; 1629637749.;
   1139833627.; 895118866.; 296359237.; 1361440746.; 1188627020.;
   1964199872.; 166733080.; 54185744.; 575493576.; 1810324496.; 1765549585.;
   53514233.; 747348448.; 61758907.; 1710119765.; 188311628.; 8827553.;
   67975851.; 1808633248.; 1290488843.; 1264775607.; 1711469075.;
   1537468597.; 706677101.; 518290019.; 190285086.; 157683412.; 985907152.;
   1571668636.; 632570698.; 791081325.; 1773794197.; 1787141077.;
   1727982894.; 794213057.; 633163306.; 682601940.; 1573439414.; 1041956036.;
   1169697582.; 758914445.; 2096291761.; 1502226099.; 1665995955.;
   948048264.; 1596326605.; 1816773893.; ...]]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/</fr:uri>
                    <fr:display-uri>focs-insertion-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-insertion-sort/</fr:route>
                    <fr:title text="Insertion Sort">Insertion Sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An insert operation does <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> comparisons on average.</html:p>
                    <html:pre><![CDATA[# let rec ins x = function
    | [] -> [x]
    | y::ys -> if x <= y then x :: y :: ys
               else y :: ins x ys
val ins : 'a -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Insertion sort</html:em> takes <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons on average:</html:p>
                    <html:pre><![CDATA[let rec insort = function
    | [] -> []
    | x::xs -> ins x (insort xs)]]></html:pre>
                    <html:p>Items from the input are copied one at a time to the output.  Each new item is
inserted into the right place so that the output is always in order.</html:p>
                    <html:p>We could easily write <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link> versions of these functions, but to no purpose.
Insertion sort is slow because it does <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> comparisons (and a lot of list
copying), not because it is recursive.  Its quadratic runtime makes it nearly
useless: it takes 174 seconds for our example while the next-worst figure is
1.4 seconds.</html:p>
                    <html:p>Insertion sort is worth considering because it is easy to code and illustrates
the concepts.  Two efficient sorting algorithms, <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link> and heapsort, can be
regarded as refinements of insertion sort.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge/</fr:uri>
                    <fr:display-uri>focs-merge</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge/</fr:route>
                    <fr:title text="Merging Two Lists">Merging Two Lists</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Merge joins two sorted lists.</html:p>
                    <html:pre><![CDATA[# let rec merge = function
    | [], ys -> ys
    | xs, [] -> xs
    | x::xs, y::ys ->
        if x <= y then
          x :: merge (xs, y::ys)
        else
          y :: merge (x::xs, ys)
val merge : 'a list * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Generalises <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insert</fr:link> to two lists, and does at most <fr:tex display="inline"><![CDATA[m+n-1]]></fr:tex> comparisons.</html:p>
                    <html:p><html:em>Merging</html:em> means combining two sorted lists to form a larger sorted list.
It does at most <fr:tex display="inline"><![CDATA[m+n]]></fr:tex> comparisons, where <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are the lengths of the
input lists.  If <fr:tex display="inline"><![CDATA[m]]></fr:tex> and <fr:tex display="inline"><![CDATA[n]]></fr:tex> are roughly equal then we have a fast way of
constructing sorted lists; if <fr:tex display="inline"><![CDATA[n=1]]></fr:tex> then merging degenerates to insertion,
doing much work for little gain.</html:p>
                    <html:p>Merging is the basis of several sorting algorithms; we look at a
divide-and-conquer one.  Mergesort is seldom found in conventional programming
because it is hard to code for arrays; it works nicely with lists.  It divides
the input (if non-trivial) into two roughly equal parts, sorts them
recursively, then merges them.</html:p>
                    <html:p>Function <html:code>merge</html:code> is not <fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">iterative</fr:link>; the recursion is deep.  An iterative
version is of little benefit for the same reasons that apply to
<fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link> in the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">earlier lecture on Lists</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/</fr:uri>
                    <fr:display-uri>focs-partial-application</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-partial-application/</fr:route>
                    <fr:title text="Partial Application: A Curried Insertion Sort">Partial Application: A Curried Insertion Sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let insort lessequal =
    let rec ins x = function
      | [] -> [x]
      | y::ys -> if lessequal x y then x :: y :: ys
                 else y :: ins x ys
    in
    let rec sort = function
      | [] -> []
      | x::xs -> ins x (sort xs)
    in
    sort
val insort : ('a -> 'a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">sorting functions</fr:link> we discussed in earlier lectures are coded to sort floating-point
numbers.  They can be generalised to an arbitrary ordered type by passing the
ordering predicate <html:code>lessequal</html:code> as an argument.</html:p>
                    <html:p>Functions <html:code>ins</html:code> and <html:code>sort</html:code> are declared locally, referring to <html:code>lessequal</html:code>.
Though it may not be obvious, <html:code>insort</html:code> is a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link>.  Given its first
argument, a predicate for comparing some particular type of items, it returns
the function <html:code>sort</html:code> for sorting lists of that type of items.</html:p>
                    <html:p>Some examples of its use:</html:p>
                    <html:pre><![CDATA[# insort (<=) [5; 3; 9; 8]
- : int list = [3; 5; 8; 9]
# insort (<=) ["bitten"; "on"; "a"; "bee"]
- : string list = ["a"; "bee"; "bitten"; "on"]
# insort (>=) [5; 3; 9; 8]
- : int list = [9; 8; 5; 3]]]></html:pre>
                    <html:p>An obscure point: the syntax <html:code>(&lt;=)</html:code> denotes the comparison operator as a
function, which is then given to <html:code>insort</html:code>.  Passing the relation <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex> for
<html:code>lessequal</html:code> gives a decreasing sort.  This is no coding trick; it is justified
in mathematics, since if <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> is a partial ordering then so is <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/</fr:uri>
                    <fr:display-uri>focs-quicksort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort/</fr:route>
                    <fr:title text="Quicksort: The Code">Quicksort: The Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec quick = function
    | [] -> []
    | [x] -> [x]
    | a::bs ->
        let rec part l r = function
          | [] -> (quick l) @ (a :: quick r)
          | x::xs ->
              if (x <= a) then
                part (x::l) r xs
              else
                part l (x::r) xs
        in
        part [] [] bs
val quick : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Our OCaml quicksort copies the items.  It is still pretty fast, and it is much
easier to understand.  It takes roughly 0.74 seconds to sort our list of random
numbers.</html:p>
                    <html:p>The function declaration consists of three clauses.  The first handles the
empty list; the second handles singleton lists (those of the form <html:code>[x]</html:code>); the
third handles lists of two or more elements.  Often, lists of length up to five
or so are treated as special cases to boost speed.</html:p>
                    <html:p>The locally declared function <html:code>part</html:code> partitions the input using <html:code>a</html:code> as the
pivot.  The arguments <html:code>l</html:code> and <html:code>r</html:code> accumulate items for the left (<fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>) and
right (<fr:tex display="inline"><![CDATA[>a]]></fr:tex>) parts of the input, respectively.</html:p>
                    <html:p>It is not hard to prove that quicksort does <fr:tex display="inline"><![CDATA[n\log  n]]></fr:tex> comparisons, <html:em>in the average case</html:em>
(see <fr:link href="https://archive.org/details/designanalysisof00ahoarich" type="external">page 94 of Aho</fr:link>).  With random data, the pivot
usually has an average value that divides the input in two approximately equal
parts.  We have the recurrence <fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>, which is
<fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex>.  In our example, it is about 235 times faster than <fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">insertion
sort</fr:link>.</html:p>
                    <html:p>In the worst case, quicksort's running time is quadratic!  An example is when
its input is almost sorted or reverse sorted.  Nearly all of the items end up
in one partition; work is not divided evenly.  We have the recurrence
<fr:tex display="inline"><![CDATA[T(1) = 1]]></fr:tex> and <fr:tex display="inline"><![CDATA[T(n+1) = T(n)+n]]></fr:tex>, which is <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex>.  Randomising the input
makes the worst case highly unlikely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/</fr:uri>
                    <fr:display-uri>focs-quicksort-idea</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-quicksort-idea/</fr:route>
                    <fr:title text="Quicksort: The Idea">Quicksort: The Idea</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The Quicksort algorithm has the following flow:</html:p>
                    <html:ul><html:li>Choose a <html:em>pivot</html:em> element, <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li>
  <html:li>Divide to partition the input into two sublists:
    <html:ul><html:li>those <html:em>at most</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex> in value</html:li>
      <html:li>those <html:em>exceeding</html:em> <fr:tex display="inline"><![CDATA[a]]></fr:tex></html:li></html:ul></html:li>
  <html:li>Conquer using recursive calls to sort the sublists</html:li>
  <html:li>Combine the sorted lists by appending one to the other</html:li></html:ul>
                    <html:p>Quicksort was invented by Sir Anthony Hoare, who works at Microsoft Research,
Cambridge.  Quicksort works by <html:em>divide and conquer,</html:em> a basic algorithm design
principle.  Quicksort chooses from the input some value <fr:tex display="inline"><![CDATA[a]]></fr:tex>, called the
<html:em>pivot</html:em>.  It partitions the remaining items into two parts: those <fr:tex display="inline"><![CDATA[\leq  a]]></fr:tex>, and
those <fr:tex display="inline"><![CDATA[>a]]></fr:tex>.  It sorts each part recursively, then puts the smaller part before
the greater.</html:p>
                    <html:p>The cleverest feature of Hoare's algorithm was that the partition could be done
<html:em>in place</html:em> by exchanging array elements.  Quicksort was invented before
<fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link> was well known, and people found it extremely hard to understand.  As
usual, we shall consider a list version based on functional programming.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting-summary/</fr:uri>
                    <fr:display-uri>focs-sorting-summary</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-sorting-summary/</fr:route>
                    <fr:title text="Summary of Sorting Algorithms">Summary of Sorting Algorithms</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Optimal is <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-insertion-sort/" title="Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-insertion-sort/" display-uri="focs-insertion-sort" type="local">Insertion sort</fr:link>: simple to code; too slow (quadratic) [174 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-quicksort/" title="Quicksort: The Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort/" display-uri="focs-quicksort" type="local">Quicksort</fr:link>: fast on average; quadratic in worst case [0.53 secs]</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">Mergesort</fr:link>: optimal in theory; often slower than quicksort [1.4 secs]</html:li>
  <html:li><html:em>Match the algorithm to the application</html:em></html:li></html:ul>
                    <html:p>Quicksort’s worst case cannot be ignored.  For large <fr:tex display="inline"><![CDATA[n]]></fr:tex>, a complexity of
<fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> is catastrophic.  Mergesort has an <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> worst case running
time, which is optimal, but it is typically slower than quicksort for random
data.</html:p>
                    <html:p>Non-comparison sorting deserves mentioning.  We can sort a large number of
small integers using their radix representation in <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time.  This result
does not contradict the comparison-counting argument because comparisons are
not used at all.  Linear time is achievable only if the greatest integer is
fixed in advance; as <fr:tex display="inline"><![CDATA[n]]></fr:tex> goes to infinity, increasingly many of the items
are the same.  It is a simple special case.</html:p>
                    <html:p>Many other sorting algorithms exist. A few are outlined in <fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">the exercises</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/</fr:uri>
                    <fr:display-uri>focs-merge-sort</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-merge-sort/</fr:route>
                    <fr:title text="Top-down Merge sort">Top-down Merge sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec tmergesort = function
    | [] -> []
    | [x] -> [x]
    | xs ->
        let k = List.length xs / 2 in
        let l = tmergesort (take k xs) in
        let r = tmergesort (drop k xs) in
        merge (l, r)
val tmergesort : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons in worst case</html:p>
                    <html:p>Mergesort’s <html:em>divide</html:em> stage divides the input not by choosing a pivot (as
in <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>) but by simply counting out half of the elements.  The
<html:em>conquer</html:em> stage again involves recursive calls, and the <html:em>combine</html:em>
stage involves merging.  Function <html:code>tmergesort</html:code> takes roughly 1.4
seconds to sort the list <html:code>rs</html:code>.</html:p>
                    <html:p>In the worst case, mergesort does <fr:tex display="inline"><![CDATA[O(n\log  n)]]></fr:tex> comparisons, with the same
recurrence equation as in quicksort’s average case.  Because <fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>take</html:code></fr:link> and
<fr:link href="/~avsm2/fcs/focs-take-drop/" title="List Utilities: take and drop" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-take-drop/" display-uri="focs-take-drop" type="local"><html:code>drop</html:code></fr:link> divide the input in two equal parts (they differ at most by
one element), we always have <fr:tex display="inline"><![CDATA[T(n) = 2T(n/2)+n]]></fr:tex>.</html:p>
                    <html:p>Quicksort is nearly 3 times as fast in the example.  But it risks a
quadratic worst case!  Merge sort is safe but slow.  So which algorithm is
best?</html:p>
                    <html:p>We have seen a <html:em>top-down</html:em> mergesort.  <html:em>Bottom-up</html:em> algorithms also
exist.  They start with a list of one-element lists and repeatedly merge
adjacent lists until only one is left.  A refinement, which exploits any
initial order among the input, is to start with a list of increasing or
decreasing runs of input items.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-3/</fr:uri>
                    <fr:display-uri>focs-ex-5-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-3/</fr:route>
                    <fr:title text="Exercises › Complexity of bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of bubble sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another sorting algorithm (bubble sort) consists of looking at adjacent pairs of elements,
exchanging them if they are out of order and repeating this process until no more exchanges are
possible. State, with justification, the time complexity of this approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-1/</fr:uri>
                    <fr:display-uri>focs-ex-5-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-1/</fr:route>
                    <fr:title text="Exercises › Complexity of selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Complexity of selection sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another sorting algorithm (selection sort) consists of looking at the elements to be sorted,
identifying and removing a minimal element, which is placed at the head of the result. The tail is
obtained by recursively sorting the remaining elements. State, with justification, the time
complexity of this approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-4/</fr:uri>
                    <fr:display-uri>focs-ex-5-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-4/</fr:route>
                    <fr:title text="Exercises › Implementing bubble sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing bubble sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement bubble sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5-2/</fr:uri>
                    <fr:display-uri>focs-ex-5-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-5-2/</fr:route>
                    <fr:title text="Exercises › Implementing selection sort"><fr:link href="/~avsm2/fcs/focs-ex-5/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-5/" display-uri="focs-ex-5" type="local">Exercises</fr:link> › Implementing selection sort</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Implement selection sort (see previous exercise) using OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-2/</fr:uri>
                    <fr:display-uri>focs-ex-8-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-2/</fr:route>
                    <fr:title text="Exercises › Lexicographic orderings"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Lexicographic orderings</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>There are many ways of combining orderings. The <html:code>lexicographic ordering</html:code> uses two keys for
comparisons. It is specified by</html:p>
                    <fr:tex display="block"><![CDATA[(x',y')<(x,y)\iff  x'<x \vee  (x'=x \wedge  y'<y).]]></fr:tex>
                    <html:p>Write an OCaml function to lexicographically combine two orderings, supplied as functions. Explain
how it allows function <fr:link href="/~avsm2/fcs/focs-partial-application/" title="Partial Application: A Curried Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/" display-uri="focs-partial-application" type="local"><html:code>insort</html:code></fr:link> to sort a list of pairs.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-datatypes/</fr:uri>
                <fr:display-uri>focs-topic-datatypes</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-datatypes/</fr:route>
                <fr:title text="Datatypes">Datatypes</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/</fr:uri>
                    <fr:display-uri>focs-constructors-args</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-constructors-args/</fr:route>
                    <fr:title text="A Datatype whose Constructors have Arguments">A Datatype whose Constructors have Arguments</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int
               | Car       of bool
               | Lorry     of int
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
                    <html:ul><html:li>Constructors with arguments (like <html:code>Lorry</html:code>) are <html:em>distinct values</html:em>. (So <html:code>Car true</html:code> is distinct from <html:code>Car false</html:code>).</html:li>
  <html:li>Different kinds of <html:code>vehicle</html:code> can belong to one list: <html:code>[Bike, Car true, Motorbike 450]</html:code></html:li></html:ul>
                    <html:p>OCaml generalises the notion of enumeration type to allow data to be associated
with each constructor.  The constructor <html:code>Bike</html:code> is a vehicle all by itself, but
the other three constructors create vehicles from arguments.</html:p>
                    <html:p>Since we might find it hard to remember what the various <html:code>int</html:code> and
<html:code>bool</html:code> components are for, it is wise to include <html:em>comments</html:em> in
complex declarations.  In OCaml, comments are enclosed in the brackets
<html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>. Programmers should comment their code to explain
design decisions and key features of the algorithms (sometimes by citing a
reference work).</html:p>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int  (* engine size in CCs *)
               | Car       of bool (* true if a Reliant Robin *)
               | Lorry     of int  (* number of wheels *)
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
                    <html:p>The list shown on the slide represents a bicycle, a Reliant Robin and a large
motorbike.  It can be almost seen as a mixed-type list containing integers and
booleans.  It is actually a list of vehicles; datatypes lessen the impact of
the restriction that all list elements must have the same type.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-wheels/</fr:uri>
                    <fr:display-uri>focs-wheels</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-wheels/</fr:route>
                    <fr:title text="A Finer Wheel Computation">A Finer Wheel Computation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We now define a <html:code>wheels</html:code> function to calculate the number of wheels
in any <html:code>vehicle</html:code>. This requires <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matching</fr:link> to retrieve the
constructors and their associated arguments, around which we build the
logic:</html:p>
                    <html:pre><![CDATA[# let wheels = function
  | Bike -> 2
  | Motorbike _ -> 2
  | Car robin -> if robin then 3 else 4
  | Lorry w -> w
val wheels : vehicle -> int = <fun>]]></html:pre>
                    <html:p>This function consists of four clauses:</html:p>
                    <html:ul><html:li>A Bike has two wheels.  This is a constant result.</html:li>
  <html:li>A Motorbike has two wheels. The <html:code>_</html:code> signifies a "wildcard" pattern match that we discard, since the engine size of the bike is not relevant to the number of wheels.</html:li>
  <html:li>A Reliant Robin has three wheels; all other cars have four. We bind <html:code>robin</html:code> to the <html:code>bool</html:code> argument and then use it in the right hand side of the pattern match, much like a <html:code>let</html:code> binding in normal code.</html:li>
  <html:li>A Lorry has the number of wheels stored with its constructor, and we simply return that.</html:li></html:ul>
                    <html:p>There is no overlap between the <html:code>Motorbike</html:code> and <html:code>Lorry</html:code> cases.  Although
<html:code>Motorbike</html:code> and <html:code>Lorry</html:code> both hold an integer, OCaml takes the
constructor into account and keeps any <html:code>Motorbike</html:code> distinct from any <html:code>Lorry</html:code>.</html:p>
                    <html:p>Vehicles are one example of a concept consisting of several varieties with
distinct features.  Most programming languages can represent such concepts
using something analogous to <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatypes</fr:link>.  (They are sometimes called
<html:em>union types</html:em> or <html:em>variant records</html:em> whose <html:em>tag fields</html:em> play the
role of the constructors.)</html:p>
                    <html:p>A pattern may be built from the constructors of several datatypes, including
lists. A pattern may also contain integer and string constants. There is no
limit to the size of patterns or the number of clauses in a function
declaration. OCaml performs pattern-matching <fr:link href="https://dl.acm.org/citation.cfm?id=507641" type="external">efficiently</fr:link>
(you do not need to understand the details of how it optimises pattern-matching at this stage).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstract-data-type/</fr:uri>
                    <fr:display-uri>focs-def-abstract-data-type</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-abstract-data-type/</fr:route>
                    <fr:title text="Abstract data type">Abstract data type</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent them. Before choosing the
internal representation for a data structure, you need to specify the full set of
operations. Abstract types can be declared in any modern programming language:
Java’s <html:em>objects</html:em> serve this role, as do OCaml’s modules.
Introduced in <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">Dictionaries</fr:link>, and applied to
<fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local">queues</fr:link> and <fr:link href="/~avsm2/fcs/focs-stacks/" title="Another Abstract Data Type: Stacks" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/" display-uri="focs-stacks" type="local">stacks</fr:link> later on.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/</fr:uri>
                    <fr:display-uri>focs-def-algebraic-datatype</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-algebraic-datatype/</fr:route>
                    <fr:title text="Algebraic datatype">Algebraic datatype</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>OCaml generalises the notion of enumeration type to allow data to be
associated with each constructor: some constructors are values all by themselves,
while others create values from arguments. Constructors with arguments are
<html:em>distinct values</html:em>, and values built from different constructors of one
datatype can belong to a single list.
Introduced in <fr:link href="/~avsm2/fcs/focs-constructors-args/" title="A Datatype whose Constructors have Arguments" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/" display-uri="focs-constructors-args" type="local">A Datatype whose Constructors have Arguments</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/</fr:uri>
                    <fr:display-uri>focs-queue-adt</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-queue-adt/</fr:route>
                    <fr:title text="An Abstract Data Type: Queues">An Abstract Data Type: Queues</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><html:code>qempty</html:code> is the <html:em>empty queue</html:em></html:li>
  <html:li><html:code>qnull</html:code> <html:em>tests</html:em> whether a queue is empty</html:li>
  <html:li><html:code>qhd</html:code> <html:em>returns</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>deq</html:code> <html:em>discards</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>enq</html:code> <html:em>adds</html:em> an element at the <html:em>end</html:em> of a queue</html:li></html:ul>
                    <html:p>Breadth-first search becomes much faster if we replace the lists by
<html:em>queues</html:em>.  A queue represents a sequence, allowing elements to be taken
from the head and added to the tail.  This is a First-In-First-Out (FIFO)
discipline: the item next to be removed is the one that has been in the queue
for the longest time.  Lists can implement queues, but <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link> is a poor means
of adding elements to the tail.</html:p>
                    <html:p>Our <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional arrays</fr:link> are suitable, provided we
augment them with a function to delete the first array element.  (See <html:em>ML
  for the Working Programmer</html:em> page 156.)  Each operation would take <fr:tex display="inline"><![CDATA[O(\log 
n)]]></fr:tex> time for a queue of length <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>We shall describe a representation of queues that is purely functional, based
upon lists, and efficient.  Operations take <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> time when “amortized”:
averaged over the lifetime of a queue.</html:p>
                    <html:p>A conventional programming technique is to represent a queue by an array.  Two
indices point to the front and back of the queue, which may wrap around the
end of the array.  The coding is somewhat tricky.  Worse, the length of the
queue must be given a fixed upper bound.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-enumeration/</fr:uri>
                    <fr:display-uri>focs-enumeration</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-enumeration/</fr:route>
                    <fr:title text="An Enumeration Type">An Enumeration Type</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We will now learn how to define more expressive types than the
basic ones supplied with the core OCaml language.</html:p>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike
               | Car
               | Lorry
type vehicle = Bike | Motorbike | Car | Lorry]]></html:pre>
                    <html:ul><html:li>We have declared a <html:em>new type</html:em> named <html:code>vehicle</html:code>.</html:li>
  <html:li><fr:tex display="inline"><![CDATA[\ldots ]]></fr:tex> along with four new constants.</html:li>
  <html:li>They are the <html:em>constructors</html:em> of the <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>.</html:li></html:ul>
                    <html:p>The <html:code>type</html:code> declaration adds a new type to our OCaml session.  Type
<html:code>vehicle</html:code> is as good as any built-in type and even admits
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> (as we used with the <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">built-in list types</fr:link> earlier).
The four new identifiers of type <html:code>vehicle</html:code> are called <html:em>constructors</html:em>.</html:p>
                    <html:p>We could represent the various vehicles by the numbers 0–3.  However, the code would be
hard to read and even harder to maintain.  Consider adding <html:code>Tricycle</html:code>
as a new vehicle. If we wanted to add it before <html:code>Bike</html:code>, then all the
numbers would have to be changed.  Using <html:code>type</html:code>, such additions are
trivial and the compiler can (at least sometimes) warn us when it encounters a
function declaration that doesn’t yet have a case for <html:code>Tricycle</html:code>.</html:p>
                    <html:p>Representing vehicles by strings like <html:code>"Bike"</html:code>, <html:code>"Car"</html:code>, etc.,
is also bad.  Comparing string values is slow and the compiler
can’t warn us of misspellings like <html:code>"MOtorbike"</html:code>: they will make our
code fail.</html:p>
                    <html:p>Most programming languages allow the declaration of types like
<html:code>vehicle</html:code>.  Because they consist of a series of identifiers, they are
called <html:em>enumeration types</html:em>.  Other common examples are days of the week
or colours.  The compiler chooses the integers for us; type-checking prevents
us from confusing <html:code>Bike</html:code> with <html:code>Red</html:code> or <html:code>Sunday</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/</fr:uri>
                    <fr:display-uri>focs-binary-trees</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-binary-trees/</fr:route>
                    <fr:title text="Binary Trees, a Recursive Datatype">Binary Trees, a Recursive Datatype</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a tree =
    Lf
  | Br of 'a * 'a tree * 'a tree
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmihauytafmmc5evdkkihzsaxper2thnogxohktuubaoxtrpw24qazu.svg" />
                    </html:figure>
                    <html:pre><![CDATA[# Br(1, Br(2, Br(4, Lf, Lf),
              Br(5, Lf, Lf)),
        Br(3, Lf, Lf))
- : int tree = Br (1, Br (2, Br (4, Lf, Lf), Br (5, Lf, Lf)), Br (3, Lf, Lf))]]></html:pre>
                    <html:p>A data structure with multiple branching is called a “tree”.  Trees can
represent mathematical expressions, logical formulae, computer programs, the
phrase structure of English sentences, etc.</html:p>
                    <html:p><html:em>Binary trees</html:em> are nearly as fundamental as lists.  They can provide
efficient storage and retrieval of information.  In a binary tree, each node
is empty (<fr:tex display="inline"><![CDATA[Lf]]></fr:tex>), or is a branch (<fr:tex display="inline"><![CDATA[Br]]></fr:tex>) with a label and two subtrees.</html:p>
                    <html:p><fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">OCaml lists</fr:link> are a <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> and could be declared as follows:</html:p>
                    <html:pre><![CDATA[# type 'a mylist =
  | Nil
  | Cons of 'a * 'a mylist
type 'a mylist = Nil | Cons of 'a * 'a mylist]]></html:pre>
                    <html:p>We could even declare <html:code>::</html:code> as an infix constructor.  The only
thing we could not define is the <html:code>[...]</html:code> notation, which is
part of the OCaml grammar (although there does exist a mechanism
to use a <html:em>similar</html:em> syntax for custom indexed datatypes).</html:p>
                    <html:p>A <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> type does not have to be <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.
For example, here is a simple datatype of tree shapes with no attached data
that is recursive but not polymorphic.</html:p>
                    <html:pre><![CDATA[# type shape =
  | Null
  | Join of shape * shape
type shape = Null | Join of shape * shape]]></html:pre>
                    <html:p>The datatype <html:code>'a option</html:code> (<fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">mentioned above</fr:link>) is the opposite – it is
polymorphic, but not recursive.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-vehicles/</fr:uri>
                    <fr:display-uri>focs-vehicles</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-vehicles/</fr:route>
                    <fr:title text="Declaring a Function on Vehicles">Declaring a Function on Vehicles</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let wheels = function
  | Bike -> 2
  | Motorbike -> 2
  | Car -> 4
  | Lorry -> 18
val wheels : vehicle -> int = <fun>]]></html:pre>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">Datatype constructors</fr:link> can be used in patterns.</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">Pattern-matching</fr:link> is fast, even complicated nested patterns.</html:li>
  <html:li>Notice the type of the argument is <html:code>vehicle</html:code>, which we defined earlier.</html:li></html:ul>
                    <html:p>The beauty of datatype declarations is that the new types behave as if they
were built into OCaml. Type-checking catches common errors, such as mixing up
different datatypes in a function like <html:code>wheels</html:code>, as well as missing
and redundant patterns.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/</fr:uri>
                    <fr:display-uri>focs-dates</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-dates/</fr:route>
                    <fr:title text="Example 1: Dates">Example 1: Dates</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">Abstract level</fr:link>: dates over a certain interval</html:li>
  <html:li>Concrete level: could be 6 characters: <html:code>YYMMDD</html:code> (where each character is represented by 8 bits)</html:li>
  <html:li>Date crises caused by <html:strong>inadequate</html:strong> internal formats:
    <html:ul><html:li>Digital’s PDP-10: using 12-bit dates (good for at most 11 years)</html:li>
      <html:li>2000 crisis: 48 bits could be good for lifetime of universe!</html:li></html:ul></html:li></html:ul>
                    <html:p>Digital Equipment Corporation’s date crisis occurred in 1975.  The
PDP-10 was a 36-bit mainframe computer. It represented dates using a 12-bit
format designed for the tiny PDP-8. With 12 bits, one can distinguish
<fr:tex display="inline"><![CDATA[2^{12} = 4096]]></fr:tex> days or 11 years.</html:p>
                    <html:p>Last century, the most common industry format for dates used six characters: two for the
year, two for the month and two for the day. The most common “solution” to the
year 2000 crisis is to add two further characters, thereby altering file sizes.
Others have noticed that the existing six characters consist of 48 bits,
already sufficient to represent all dates over the projected lifetime of the
universe: <fr:tex display="inline"><![CDATA[2^{48}]]></fr:tex> = <fr:tex display="inline"><![CDATA[2.8\times  10^{14}]]></fr:tex> days = <fr:tex display="inline"><![CDATA[7.7\times  10^{11}]]></fr:tex> years!</html:p>
                    <html:p>Mathematicians think in terms of unbounded ranges, but the representation we
choose for the computer usually imposes hard limits. A good programming
language like OCaml lets one easily change the representation used in the
program.  But if files in the old representation exist all over the place,
there will still be conversion problems. The need for compatibility with older
systems causes problems across the computer industry.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/</fr:uri>
                    <fr:display-uri>focs-ocaml-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ocaml-exceptions/</fr:route>
                    <fr:title text="Exceptions in OCaml">Exceptions in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Failure
exception Failure
# exception NoChange of int
exception NoChange of int
# raise Failure
Exception: Failure.]]></html:pre>
                    <html:p>Each <html:code>exception</html:code> declaration introduces a distinct sort of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link>, which can
be handled separately from others. If <fr:tex display="inline"><![CDATA[E]]></fr:tex> raises an exception, then its
evaluation has failed; <html:em>handling</html:em> an exception means evaluating another
expression and returning its value instead. One exception handler can specify
separate expressions for different sorts of exceptions.</html:p>
                    <html:p>Exception names are <html:em>constructors</html:em> of the special <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> <html:code>exn</html:code>.  This is a
peculiarity of OCaml that lets exception-handlers use <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>. Note that
exception <html:code>Failure</html:code> is just an error indication, while <html:code>NoChange n</html:code> carries
further information: the integer <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# try
    print_endline "pre exception";
    raise (NoChange 1);
    print_endline "post exception";
  with
    | NoChange _ ->
        print_endline "handled a NoChange exception"
Line 3, characters 5-23:
Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.)
pre exception
handled a NoChange exception
- : unit = ()]]></html:pre>
                    <html:p>The effect of <html:code>raise &lt;expr&gt;</html:code> is to jump to the most recently-encountered
handler that matches <html:code>&lt;expr&gt;</html:code>.  The matching handler can only be found
<html:em>dynamically</html:em> (during execution); contrast with how OCaml associates occurrences
of identifiers with their matching declarations, which does not require running
the program.  A handler is introduced via the <html:code>try</html:code> keyword, which executes
the subexpression and dispatches any exceptions encountered to the corresponding
pattern match for exceptions defined in the <html:code>with</html:code> block.</html:p>
                    <html:p>This is also the first time that we have encountered the <html:code>unit</html:code> type. This
represents a type that has no values, and is used to indicate that a block
has no meaningful return value.  We will come back to this when learning more
about <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local"><html:em>imperative</html:em> programming</fr:link> later on.  For now, it is sufficient to understand
that <html:code>print_endline</html:code> will print out the argument to the console output, and return
a <html:code>unit</html:code> type.  The semicolon at the end of the expression is a convenient way to
execute sequential statements that return the <html:code>unit</html:code> type.</html:p>
                    <html:p>One criticism of OCaml’s exceptions is that—unlike the Java language—nothing
in a function declaration indicates which exceptions it might raise. One
alternative to exceptions is to instead return a value of datatype <html:code>option</html:code>.</html:p>
                    <html:pre><![CDATA[# let x = Some 1
val x : int option = Some 1
# let y = None
val y : 'a option = None
# type 'a option = None | Some of 'a
type 'a option = None | Some of 'a]]></html:pre>
                    <html:p><html:code>None</html:code> signifies an error, while <html:code>Some x</html:code> returns the solution <fr:tex display="inline"><![CDATA[x]]></fr:tex>.  This
approach looks clean, but the drawback is that many places in the code would
have to check for <html:code>None</html:code>.  Despite this, there is a builtin <html:code>option</html:code> type
in OCaml as it is so useful. We will see in later lectures how to define our
own version of <html:code>option</html:code> using polymorphic datatype definitions.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-ocaml/</fr:uri>
                    <fr:display-uri>focs-lazy-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-lazy-ocaml/</fr:route>
                    <fr:title text="Lazy Lists in OCaml">Lazy Lists in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>The empty tuple <html:code>()</html:code> and its <html:em>type</html:em> <html:code>unit</html:code></html:li>
  <html:li>Delayed version of <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:code>fun () -&gt; E</html:code></html:li></html:ul>
                    <html:pre><![CDATA[# type 'a seq =
  | Nil
  | Cons of 'a * (unit -> 'a seq)
type 'a seq = Nil | Cons of 'a * (unit -> 'a seq)
# let head (Cons (x, _)) = x
Line 1, characters 10-27:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val head : 'a seq -> 'a = <fun>
# let tail (Cons (_, xf)) = xf ()
Line 1, characters 10-32:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val tail : 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[\tt  Cons(x, xf)]]></fr:tex> has <html:em>head</html:em> <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <html:em>tail function</html:em> <fr:tex display="inline"><![CDATA[xf]]></fr:tex></html:p>
                    <html:p>The primitive OCaml type <html:code>unit</html:code> has one element, which is
written <html:code>()</html:code>.  This element may be regarded as a 0-tuple, and
<html:code>unit</html:code> as the nullary Cartesian product.  (Think of the connection
between multiplication and the number 1.)</html:p>
                    <html:p>The empty tuple serves as a placeholder in situations where no information is
required.  It may:</html:p>
                    <html:ul><html:li>appear in a data structure.  For example, a <html:code>unit</html:code>-valued <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">dictionary</fr:link> represents a set of keys.</html:li>
  <html:li>be the argument of a function, where its effect is to <html:em>delay evaluation</html:em>.</html:li>
  <html:li>be the argument or result of a procedure. (see the <fr:link href="/~avsm2/fcs/focs-procedural-programming/" title="Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/" display-uri="focs-procedural-programming" type="local">Procedural Programming section</fr:link>)</html:li></html:ul>
                    <html:p>The empty tuple, like all tuples, is a constructor and is allowed in patterns;
for example: <html:code>let f () = ...</html:code></html:p>
                    <html:p>In particular <fr:tex display="inline"><![CDATA[\tt  fun \, () \rightarrow  E]]></fr:tex> is the function that takes an argument of
type <html:code>unit</html:code> and returns the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as its result.  Expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>
is not evaluated until the function is called, even though the only possible
argument is <html:code>()</html:code>.  The function simply delays the evaluation of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/</fr:uri>
                    <fr:display-uri>focs-def-pattern-matching</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-pattern-matching/</fr:route>
                    <fr:title text="Pattern matching">Pattern matching</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Pattern matching takes a value apart by matching it against the forms that
value can have, letting <html:em>one</html:em> function declaration handle several cases,
separated by a vertical bar <html:code>|</html:code>. Taking a list apart using combinations of
<html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right; fortunately, it is seldom necessary
because of pattern-matching.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-comparison/</fr:uri>
                    <fr:display-uri>focs-references-comparison</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references-comparison/</fr:route>
                    <fr:title text="References: OCaml vs conventional languages">References: OCaml vs conventional languages</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>We must write <html:code>!p</html:code> to get the <html:em>contents</html:em> of <html:code>p</html:code></html:li>
  <html:li>We write just <html:code>p</html:code> for the <html:em>address</html:em> of <html:code>p</html:code></html:li>
  <html:li>We can store private <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference cells</fr:link> (like <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>balance</html:code></fr:link>) in functions—analogous to elements of <html:em>object-oriented programming</html:em></html:li>
  <html:li>OCaml’s assignment syntax is <fr:tex display="inline"><![CDATA[\tt  V \, := \, E]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[V]]></fr:tex> = <fr:tex display="inline"><![CDATA[E]]></fr:tex></html:li>
  <html:li>OCaml has few control structures: <fr:link href="/~avsm2/fcs/focs-while/" title="Iteration: the while command" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/" display-uri="focs-while" type="local"><html:code>while</html:code></fr:link>, <html:code>match</html:code>, <html:code>if</html:code> and <html:code>for</html:code> (the latter is not covered in this course)</html:li>
  <html:li>OCaml has syntax for updating an array via the <html:code>a.(i) &lt;- v</html:code> syntax which is the same as <fr:link href="/~avsm2/fcs/focs-array-primitives/" title="OCaml Primitives for Arrays" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/" display-uri="focs-array-primitives" type="local"><html:code>Array.set a i v</html:code></fr:link>.</html:li></html:ul>
                    <html:p>Conventional syntax for variables and assignments has hardly changed since
Fortran, the first high-level language. In conventional languages,
virtually all variables can be updated.  We declare something like
<html:code>p: int</html:code>, mentioning no reference type even if the language provides
them.  If we do not specify an initial value, we may get whatever bits were
previously at that address.  Illegal values arising from uninitialised
variables can cause errors that are almost impossible to diagnose.</html:p>
                    <html:p>Dereferencing operators (like OCaml’s <html:code>!</html:code>) are especially unpopular, because
they clutter the program text. Virtually all programming languages make dereferencing
implicit (that is, automatic).</html:p>
                    <html:p>It is generally accepted these days that a two-dimensional array <fr:tex display="inline"><![CDATA[A]]></fr:tex> is nothing
but an array of arrays.  An assignment to such an array is typically written
something like <fr:tex display="inline"><![CDATA[A[i,j] {:=} x]]></fr:tex>; in C, the syntax is <html:code>A[i][j] = x</html:code>. Higher
dimensions are treated analogously.  The corresponding OCaml code can either
declare an array of arrays, or use the <html:code>A.(i)</html:code> syntax to calculate the linear
offset into a single array.</html:p>
                    <html:p>You can use the constructs we have learnt to easily create linked (mutable) lists as
an alternative to arrays.</html:p>
                    <html:pre><![CDATA[# type 'a mlist =
  | Nil
  | Cons of 'a * 'a mlist ref
type 'a mlist = Nil | Cons of 'a * 'a mlist ref]]></html:pre>
                    <html:p>It is worth mentioning that OCaml’s references fully suffice for coding the sort of linked data structures
taught in algorithms courses, and is illustrated in the figure above. The
programming style is a little different from the usual, but the principles are
the same.  OCaml also provides comprehensive input/output primitives for various
types of file and operating system.</html:p>
                    <html:p>OCaml’s system of modules include <html:em>structures,</html:em> which can be seen as encapsulated
groups of declarations, and <html:em>signatures,</html:em> which are specifications of
structures listing the name and type of each component.  Finally, there are
<html:em>functors,</html:em> which are analogous to functions that combine a number of argument
structures, and which can be used to plug program components together. These
primitives are useful for managing large programming projects.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/</fr:uri>
                    <fr:display-uri>focs-list-primitives</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-list-primitives/</fr:route>
                    <fr:title text="The List Primitives">The List Primitives</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>There are two kinds of lists:</html:p>
                    <html:ul><html:li><html:code>[]</html:code> represents the empty list</html:li>
  <html:li><html:code>x :: l</html:code> is the list with head <fr:tex display="inline"><![CDATA[x]]></fr:tex> and tail <fr:tex display="inline"><![CDATA[l]]></fr:tex></html:li></html:ul>
                    <html:pre><![CDATA[# let nil = []
val nil : 'a list = []
# 1 :: nil
- : int list = [1]
# 1 :: 2 :: nil
- : int list = [1; 2]]]></html:pre>
                    <html:p>The operator <html:code>::</html:code> (also called <html:code>List.cons</html:code> for “construct”), puts a new element on
to the head of an existing list.  While we should not be too preoccupied with
implementation details, it is essential to know that <html:code>::</html:code> is an <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>
operation.  It uses constant time and space, regardless of the length of the
resulting list.  Lists are represented internally with a linked structure;
adding a new element to a list merely hooks the new element to the front of
the existing structure.  Moreover, that structure continues to denote the same
list as it did before; to see the new list, one must look at the new <html:code>::</html:code> node
(or “cons cell”) just created.  We will explain the <html:code>'a</html:code> notation in the next
section.</html:p>
                    <html:p>Here we see the element <html:code>1</html:code> being consed to the front of the list <html:code>[3; 5; 9]</html:code>:</html:p>
                    <fr:tex display="block"><![CDATA[\begin{array}{ccccccccccc}
:: & \to & \cdots & :: & \to &  :: & \to &  :: & \to & [] \\
\downarrow &  &        & \downarrow &  & \downarrow &  & \downarrow  \\
1     &  &        & 3     &  & 5     &  & 9
\end{array}]]></fr:tex>
                    <html:p>Given a list, taking its first element (its “head”) or its list of
remaining elements (its “tail”) also takes constant time.  Each
operation just follows a link.  In the diagram above, the first down arrow
leads to the head and the leftmost right arrow leads to the tail.  Once we
have the tail, its head is the second element of the original list, etc.</html:p>
                    <html:p>The tail is <html:em>not</html:em> the last element; it is the <html:em>list</html:em> of all elements
other than the head!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-4/</fr:uri>
                    <fr:display-uri>focs-ex-8-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-4/</fr:route>
                    <fr:title text="Exercises › A map for options"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › A map for options</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The type <html:code>'a option</html:code>, declared below, can be viewed as a type of lists having at most one element.
(It is typically used as an alternative to <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">exceptions</fr:link>.) Declare an analogue of the function <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>
for type <html:code>'a option</html:code>.</html:p>
                    <html:pre><![CDATA[type 'a option = None | Some of 'a]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-4/</fr:uri>
                    <fr:display-uri>focs-ex-6-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-4/</fr:route>
                    <fr:title text="Exercises › A type for arithmetic expressions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › A type for arithmetic expressions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Give the declaration of an OCaml type for arithmetic expressions that have the following
possibilities: floating-point numbers, variables (represented by strings), or expressions of the form <fr:tex display="inline"><![CDATA[-E]]></fr:tex>,
<fr:tex display="inline"><![CDATA[E+E]]></fr:tex>, <fr:tex display="inline"><![CDATA[E\times  E]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-1/</fr:uri>
                    <fr:display-uri>focs-ex-6-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-1/</fr:route>
                    <fr:title text="Exercises › Days of the week type"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Days of the week type</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Give the declaration of an OCaml type for the days of the week. Comment on the practicality of such
a type in a calendar application.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-5/</fr:uri>
                    <fr:display-uri>focs-ex-6-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-5/</fr:route>
                    <fr:title text="Exercises › Evaluating expressions with exceptions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Evaluating expressions with exceptions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Continuing the previous exercise, write a function that evaluates an expression. If the expression
contains any variables, your function should raise an <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> indicating the variable name.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-4/</fr:uri>
                    <fr:display-uri>focs-ex-9-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-4/</fr:route>
                    <fr:title text="Exercises › Lazy binary trees"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Lazy binary trees</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>lazy binary tree</html:em> is either empty or is a branch containing a label and two lazy <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>,
possibly to infinite depth. Present an OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> to represent lazy binary trees, along with a
function that accepts a lazy binary tree and produces a lazy list that contains all of the tree’s
labels. (Taken from the exam question 2008 Paper 1 Question 5.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-trees/</fr:uri>
                <fr:display-uri>focs-topic-trees</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-trees/</fr:route>
                <fr:title text="Trees">Trees</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-search-methods/</fr:uri>
                    <fr:display-uri>focs-search-methods</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-search-methods/</fr:route>
                    <fr:title text="A Survey of Search Methods">A Survey of Search Methods</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Depth-first: use a <html:em>stack</html:em>  (efficient but incomplete)</html:li>
  <html:li>Breadth-first: use a <html:em>queue</html:em> (uses too much space!)</html:li>
  <html:li>Iterative deepening: use depth-first to get benefits of breadth-first (trades time for space)</html:li>
  <html:li>Best-first: use a <html:em>priority queue</html:em> (heuristic search)</html:li></html:ul>
                    <html:p>The data structure determines the search!</html:p>
                    <html:p>Search procedures can be classified by the data structure used to store
pending subtrees.  Depth-first search stores them on a stack, which is
implicit in functions like <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link>, but can be made explicit.
Breadth-first search stores such nodes in a queue.</html:p>
                    <html:p>An important variation is to store the nodes in a priority queue, which
is an ordered sequence.  The priority queue applies some sort of ranking
function to the nodes, placing higher-ranked nodes before lower-ranked ones.
The ranking function typically estimates the distance from the node to a
solution.  If the estimate is good, the solution is located swiftly.  This
method is called best-first search.</html:p>
                    <html:p>The priority queue can be kept as a sorted list, although this is slow.
<fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary search trees</fr:link> would be much better on average, and fancier data
structures improve matters further.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/</fr:uri>
                    <fr:display-uri>focs-tree-traversal</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal/</fr:route>
                    <fr:title text="Aside: Traversing Trees (3 Methods)">Aside: Traversing Trees (3 Methods)</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec preorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      [v] @ preorder t1 @ preorder t2
val preorder : 'a tree -> 'a list = <fun>
# let rec inorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      inorder t1 @ [v] @ inorder t2
val inorder : 'a tree -> 'a list = <fun>
# let rec postorder = function
  | Lf -> []
  | Br (v, t1, t2) ->
      postorder t1 @ postorder t2 @ [v]
val postorder : 'a tree -> 'a list = <fun>]]></html:pre>
                    <html:p><html:em>Tree traversal</html:em> means examining each node of a tree in some order.  <fr:link href="https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming" type="external">D. E.
Knuth</fr:link> has
identified three forms of tree traversal: preorder, inorder and
postorder.  We can code these “visiting orders” as functions
that convert trees into lists of labels.  Algorithms based on these notions
typically perform some action at each node; the functions above simply copy
the nodes into lists.  Consider the tree:</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmic3wbal56lpqlso6xcqsl6jfrutwygavrn3xds7c6ieywfjr7qdhm.svg" />
                    </html:figure>
                    <html:ul><html:li><html:code>preorder</html:code> visits the label first (“Polish notation”), yielding <html:code>ABDECFG</html:code></html:li>
<html:li><html:code>inorder</html:code> visits the label midway, yielding <html:code>DBEAFCG</html:code></html:li>
<html:li><html:code>postorder</html:code> visits the label last (“Reverse Polish”), yielding <html:code>DEBFGCA</html:code>. You might be familiar with this concept if you own an ancient RPN calculator!</html:li></html:ul>
                    <html:p>What is the use of <html:code>inorder</html:code>? Consider applying it to a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>: the
result is a sorted list of pairs. We could use this, for example, to merge two
binary search trees. It is not difficult to transform a sorted list of pairs
into a binary search tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-properties/</fr:uri>
                    <fr:display-uri>focs-tree-properties</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-properties/</fr:route>
                    <fr:title text="Basic Properties of Binary Trees">Basic Properties of Binary Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec count = function
  | Lf -> 0  (* number of branch nodes *)
  | Br (v, t1, t2) -> 1 + count t1 + count t2
val count : 'a tree -> int = <fun>
# let rec depth = function
  | Lf -> 0  (* length of longest path *)
  | Br (v, t1, t2) -> 1 + max (depth t1) (depth t2)
val depth : 'a tree -> int = <fun>]]></html:pre>
                    <html:p>The invariant <fr:tex display="inline"><![CDATA[\texttt {count}(t)\le  2^{\texttt {depth}(t)} - 1]]></fr:tex> holds in the functions above.</html:p>
                    <html:p>Functions on trees are expressed recursively using <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.  Both
functions above are analogous to <fr:link href="/~avsm2/fcs/focs-length/" title="Efficiently Computing the Length of a List" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-length/" display-uri="focs-length" type="local"><fr:tex display="inline"><![CDATA[\texttt {length}]]></fr:tex> on lists</fr:link>.  Here is a third
measure of a tree’s size:</html:p>
                    <html:pre><![CDATA[# let rec leaves = function
  | Lf -> 1
  | Br (v, t1, t2) -> leaves t1 + leaves t2
val leaves : 'a tree -> int = <fun>]]></html:pre>
                    <html:p>This function is redundant because of a basic fact about trees, which can be
proved by induction: for every tree <fr:tex display="inline"><![CDATA[t]]></fr:tex>, we have <fr:tex display="inline"><![CDATA[\texttt {leaves}(t) =
\texttt {count}(t)+1]]></fr:tex>.  The inequality shown on the slide also has an elementary
proof by induction.</html:p>
                    <html:p>A tree of depth 20 can store <fr:tex display="inline"><![CDATA[2^{20}-1]]></fr:tex> or approximately one million elements.
The access paths to these elements are short, particularly when compared with
a million-element list!</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/</fr:uri>
                    <fr:display-uri>focs-bst</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst/</fr:route>
                    <fr:title text="Binary Search Trees">Binary Search Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>dictionary</html:em> associates <html:em>values</html:em> (here, numbers) with <html:em>keys</html:em>.</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifkdrvs6ut5buyf724655gdcinx637uevqiaejsmb2jgu36gaf4wq.svg" />
                    </html:figure>
                    <html:p>Binary search trees are an important application of <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>.  They work
for keys that have a total ordering, such as strings.  Each branch of the tree
carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree holds smaller keys; the right
subtree holds greater keys.  If the tree remains reasonably balanced, then
update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  These times
hold in the average case; given random data, the tree is likely to remain
balanced.</html:p>
                    <html:p>At a given node, all keys in the left subtree are smaller (or equal) while all
trees in the right subtree are greater.</html:p>
                    <html:p>An unbalanced tree has a linear access time in the worst case.  Examples
include building a tree by repeated insertions of elements in increasing or
decreasing order; there is a close resemblance to <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>.  Building a binary
search tree, then converting it to <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">inorder</fr:link>, yields a sorting algorithm called
<html:em>treesort</html:em>.</html:p>
                    <html:p>Self-balancing trees, such as Red-Black trees, attain <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> in the worst
case.  They are complicated to implement.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/</fr:uri>
                    <fr:display-uri>focs-binary-trees</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-binary-trees/</fr:route>
                    <fr:title text="Binary Trees, a Recursive Datatype">Binary Trees, a Recursive Datatype</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a tree =
    Lf
  | Br of 'a * 'a tree * 'a tree
type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmihauytafmmc5evdkkihzsaxper2thnogxohktuubaoxtrpw24qazu.svg" />
                    </html:figure>
                    <html:pre><![CDATA[# Br(1, Br(2, Br(4, Lf, Lf),
              Br(5, Lf, Lf)),
        Br(3, Lf, Lf))
- : int tree = Br (1, Br (2, Br (4, Lf, Lf), Br (5, Lf, Lf)), Br (3, Lf, Lf))]]></html:pre>
                    <html:p>A data structure with multiple branching is called a “tree”.  Trees can
represent mathematical expressions, logical formulae, computer programs, the
phrase structure of English sentences, etc.</html:p>
                    <html:p><html:em>Binary trees</html:em> are nearly as fundamental as lists.  They can provide
efficient storage and retrieval of information.  In a binary tree, each node
is empty (<fr:tex display="inline"><![CDATA[Lf]]></fr:tex>), or is a branch (<fr:tex display="inline"><![CDATA[Br]]></fr:tex>) with a label and two subtrees.</html:p>
                    <html:p><fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">OCaml lists</fr:link> are a <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> and could be declared as follows:</html:p>
                    <html:pre><![CDATA[# type 'a mylist =
  | Nil
  | Cons of 'a * 'a mylist
type 'a mylist = Nil | Cons of 'a * 'a mylist]]></html:pre>
                    <html:p>We could even declare <html:code>::</html:code> as an infix constructor.  The only
thing we could not define is the <html:code>[...]</html:code> notation, which is
part of the OCaml grammar (although there does exist a mechanism
to use a <html:em>similar</html:em> syntax for custom indexed datatypes).</html:p>
                    <html:p>A <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive</fr:link> type does not have to be <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>.
For example, here is a simple datatype of tree shapes with no attached data
that is recursive but not polymorphic.</html:p>
                    <html:pre><![CDATA[# type shape =
  | Null
  | Join of shape * shape
type shape = Null | Join of shape * shape]]></html:pre>
                    <html:p>The datatype <html:code>'a option</html:code> (<fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">mentioned above</fr:link>) is the opposite – it is
polymorphic, but not recursive.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/</fr:uri>
                    <fr:display-uri>focs-def-binary-search-tree</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-binary-search-tree/</fr:route>
                    <fr:title text="Binary search tree">Binary search tree</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A binary search tree works for keys that have a total ordering, such as
strings. Each branch of the tree carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree
holds smaller keys and its right subtree holds greater keys. If the tree remains
reasonably balanced, then update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of
size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary Search Trees</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/</fr:uri>
                    <fr:display-uri>focs-bfs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-append/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Append">Breadth-First Tree Traversal — Using Append</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nbreadth = function
  | [] -> []
  | Lf :: ts -> nbreadth ts
  | Br (v, t, u) :: ts ->
      v :: nbreadth (ts @ [t; u])
val nbreadth : 'a tree list -> 'a list = <fun>]]></html:pre>
                    <html:p>Keeps an <html:em>enormous queue</html:em> of nodes of search, and is a wasteful use of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.</html:p>
                    <html:p>Breadth-first search can be inefficient, this naive implementation especially
so.  When the search is at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> of the tree, the list contains all the
remaining trees at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex>, followed by the subtrees (all at depth <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>) of
the trees that have already been visited.  At depth 10, the list could already
contain 1024 elements.  It requires a lot of space, and aggravates this with a
gross misuse of append.  Evaluating <html:code>ts@[t, u]</html:code> copies the long list
<html:code>ts</html:code> just to insert two elements.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/</fr:uri>
                    <fr:display-uri>focs-bfs-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-queues/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Queues">Breadth-First Tree Traversal — Using Queues</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec breadth q =
    if qnull q then []
    else
      match qhd q with
      | Lf -> breadth (deq q)
      | Br (v, t, u) -> v :: breadth (enq (enq (deq q) t) u)
val breadth : 'a tree queue -> 'a list = <fun>]]></html:pre>
                    <html:p>This function implements the same algorithm as <fr:link href="/~avsm2/fcs/focs-bfs-append/" title="Breadth-First Tree Traversal — Using Append" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/" display-uri="focs-bfs-append" type="local"><html:code>nbreadth</html:code></fr:link> but uses a different
data structure.  It represents queues using type <fr:link href="/~avsm2/fcs/focs-functional-queues/" title="Efficient Functional Queues: Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/" display-uri="focs-functional-queues" type="local"><html:code>queue</html:code></fr:link> instead of type
<html:code>list</html:code>.</html:p>
                    <html:p>To compare their efficiency, I applied both functions to the full binary tree
of depth 12, which contains 4095 labels.  The function <html:code>nbreadth</html:code> took 30
seconds while <html:code>breadth</html:code> took only 0.15 seconds: faster by a factor of 200.</html:p>
                    <html:p>For larger trees, the speedup would be greater.  Choosing the right data
structure pays handsomely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/</fr:uri>
                    <fr:display-uri>focs-bfs-dfs</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-dfs/</fr:route>
                    <fr:title text="Breadth-First v Depth-First Tree Traversal">Breadth-First v Depth-First Tree Traversal</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>binary trees as <html:em>decision trees</html:em></html:li>
  <html:li>look for <html:em>solution nodes</html:em>
    <html:ul><html:li>Depth-first: search one subtree in full before moving on</html:li>
      <html:li>Breadth-first: search all nodes at level <fr:tex display="inline"><![CDATA[k]]></fr:tex> before moving to <fr:tex display="inline"><![CDATA[k+1]]></fr:tex></html:li></html:ul></html:li>
  <html:li>finds <html:em>all</html:em> solutions — nearest first!</html:li></html:ul>
                    <html:p><fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">Preorder, inorder and postorder tree traversals</fr:link> all have something in common:
they are depth-first.  At each node, the left subtree is entirely
traversed before the right subtree.  Depth-first traversals are easy to code
and can be efficient, but they are ill-suited for some problems.</html:p>
                    <html:p>Suppose the tree represents the possible moves in a puzzle, and the purpose
of the traversal is to search for a node containing a solution.  Then a
depth-first traversal may find one solution node deep in the left subtree,
when another solution is at the very top of the right subtree.  Often we
want the shortest path to a solution.</html:p>
                    <html:p>Suppose the tree is <html:em>infinite</html:em> or simply extremely large.  Depth-first search
is almost useless with such trees, for if the left subtree is infinite then the
search will never reach the right subtree.  OCaml can represent infinite trees by
the means discussed in the <fr:link href="/~avsm2/fcs/focs-sequences/" title="Sequences, or Lazy Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sequences/" display-uri="focs-sequences" type="local">lecture on laziness</fr:link>. Another tree representation (suitable
for solving solitaire, for example) is by a function <html:code>next : pos -&gt; pos list</html:code>,
which maps a board position to a list of the positions possible after
the next move.  For simplicity, the examples below use the OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>
<fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local"><html:code>tree</html:code></fr:link>, which has only finite trees.</html:p>
                    <html:p>A <html:em>breadth-first</html:em> traversal explores the nodes horizontally rather than
vertically.  When visiting a node, it does not traverse the subtrees until
it has visited all other nodes at the current depth.  This is easily
implemented by keeping a list of trees to visit.  Initially, this list
consists of one element: the entire tree.  Each iteration removes a tree
from the head of the list and adds its subtrees after the end of the
list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/</fr:uri>
                    <fr:display-uri>focs-tree-traversal-efficient</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-tree-traversal-efficient/</fr:route>
                    <fr:title text="Efficiently Traversing Trees">Efficiently Traversing Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Unfortunately, the functions shown on the previous slide are quadratic in the
worst case: the appends in the recursive calls are inefficient.  To correct
that problem, we (as usual) add an accumulating argument.  Observe how
each function constructs its result list and compare with how appends were
eliminated from <html:code>quicksort</html:code> in the <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">Sorting lecture</fr:link>.</html:p>
                    <html:pre><![CDATA[# let rec preord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      v :: preord (t1, preord (t2, vs))
val preord : 'a tree * 'a list -> 'a list = <fun>
# let rec inord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      inord (t1, v::inord (t2, vs))
val inord : 'a tree * 'a list -> 'a list = <fun>
# let rec postord = function
  | Lf, vs -> vs
  | Br (v, t1, t2), vs ->
      postord (t1, postord (t2, v::vs))
val postord : 'a tree * 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>One can prove equations relating each of these functions to its counterpart on
the previous section.  For example:</html:p>
                    <fr:tex display="block"><![CDATA[\texttt {inord}(t, vs) = \texttt {inorder}(t) @ vs]]></fr:tex>
                    <html:p>These three types of tree traversal are related in that all are depth-first.
They each traverse the left subtree in full before traversing the right
subtree.  Breadth-first search (from the <fr:link href="/~avsm2/fcs/focs-queues/" title="Queues and Search Strategies" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queues/" display-uri="focs-queues" type="local">Queues lecture</fr:link>) is another
possibility.  That involves going through the levels of a tree one at a time.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/</fr:uri>
                    <fr:display-uri>focs-functional-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-arrays/</fr:route>
                    <fr:title text="Functional Arrays as Binary Trees">Functional Arrays as Binary Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The path to element <fr:tex display="inline"><![CDATA[i]]></fr:tex> follows the <html:em>binary code</html:em> for <fr:tex display="inline"><![CDATA[i]]></fr:tex> (its “subscript”).</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifetc2v73r7qxnzo6bthiblab2tezbaqvmovq7e4q6vgdl5ewr3wi.svg" />
                    </html:figure>
                    <html:p>This simple representation (credited to W. Braun) ensures that the tree is
balanced.  Complexity of access is always <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>, which is optimal.  For
actual running time, access to conventional arrays is much faster: it requires
only a few hardware instructions.  Array access is often taken to be <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>,
which (as always) presumes that hardware limits are never exceeded.</html:p>
                    <html:p>The lower bound for array subscripts (or “indices”) is one.  The upper bound starts at zero
(which signifies the empty array) and can grow without limit.  Inspection of
the diagram above should make it clear that these trees are always balanced:
the left subtree can have at most one node more than the right subtree,
recursively all the way down.  (This assumes that the array is defined for
subscripts <fr:tex display="inline"><![CDATA[1\ldots  n]]></fr:tex> with no gaps; an array defined only for odd numbers, for
example, would obviously be unbalanced.)</html:p>
                    <html:p>The numbers in the diagram above are not the labels of branch nodes, but
indicate the positions of array elements. For example, the label corresponding
to <fr:tex display="inline"><![CDATA[A[2]]]></fr:tex> is at the position shown. The nodes of a functional array are
labelled with the data we want to store, not with these integers.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/</fr:uri>
                    <fr:display-uri>focs-iterative-deepening</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-iterative-deepening/</fr:route>
                    <fr:title text="Iterative deepening: Another Exhaustive Search">Iterative deepening: Another Exhaustive Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Breadth-first search examines <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> nodes:
    <fr:tex display="block"><![CDATA[1 + b + \cdots  + b^d = {b^{d+1}-1 \over  b-1}
  \qquad  \begin {array}[c]{rl}
            b & {} = \hbox {branching factor}\\
            d & {} = \hbox {depth}
          \end {array}]]></fr:tex></html:li>
  <html:li>Recompute nodes at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> instead of storing them</html:li>
  <html:li>Time factor is <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>; complexity is still <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex></html:li>
  <html:li>Space required at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> drops from <fr:tex display="inline"><![CDATA[b^d]]></fr:tex> to <fr:tex display="inline"><![CDATA[d]]></fr:tex></html:li></html:ul>
                    <html:p>Breadth-first search is not practical for infinite trees: it uses too much
space. Large parts of the tree have to be stored.
Consider the slightly more general problem of searching trees whose
branching factor is <fr:tex display="inline"><![CDATA[b]]></fr:tex> (for binary trees, <fr:tex display="inline"><![CDATA[b=2]]></fr:tex>).  Then breadth-first search
to depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> examines <fr:tex display="inline"><![CDATA[(b^{d+1}-1)/(b-1)]]></fr:tex> nodes, which is <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>, ignoring
the constant factor of <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex>.  Since all nodes that are examined are also
stored, the space and time requirements are both <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.</html:p>
                    <html:p><html:em>Depth-first iterative deepening</html:em> combines the space efficiency of
depth-first with the “nearest-first” property of breadth-first search.  It
performs repeated depth-first searches with increasing depth bounds, each time
discarding the result of the previous search.  Thus it searches to depth 1,
then to depth 2, and so on until it finds a solution.  We can afford to
discard previous results because the number of nodes is growing exponentially.
There are <fr:tex display="inline"><![CDATA[b^{d+1}]]></fr:tex> nodes at level <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>; if <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex>, this number actually
exceeds the total number of nodes of all previous levels put together, namely
<fr:tex display="inline"><![CDATA[(b^{d+1}-1) / (b-1)]]></fr:tex>.</html:p>
                    <html:p><fr:link href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288" type="external">Korf shows</fr:link> that the time needed for iterative deepening to reach
depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> is only <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> times that for breadth-first search, if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>.
This is a constant factor; both algorithms have the same time complexity,
<fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.  In typical applications where <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex> the extra factor of
<fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> is quite tolerable.  The reduction in the space requirement is
exponential, from <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> for breadth-first to <fr:tex display="inline"><![CDATA[O(d)]]></fr:tex> for iterative
deepening. Of course, this assumes that the tree itself is not stored in memory.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/</fr:uri>
                    <fr:display-uri>focs-bst-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-lookup/</fr:route>
                    <fr:title text="Lookup: Seeks Left or Right">Lookup: Seeks Left or Right</fr:title>
                    <fr:meta name="ocaml-deps">focs-binary-trees</fr:meta>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Missing of string
exception Missing of string
# let rec lookup b = function
  | Br ((a, x), t1, t2) ->
      if b < a then
        lookup b t1
      else if a < b then
        lookup b t2
      else
        x
  | Lf -> raise (Missing b)
val lookup : string -> (string * 'a) tree -> 'a = <fun>]]></html:pre>
                    <html:p>This has guaranteed <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> access time <html:em>if</html:em> the tree is balanced!</html:p>
                    <html:p>Lookup in the <fr:link href="/~avsm2/fcs/focs-def-binary-search-tree/" title="Binary search tree" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/" display-uri="focs-def-binary-search-tree" type="local">binary search tree</fr:link> goes to the left subtree if the desired
key is smaller than the current one and to the right if it is greater.
It raises <html:code>Missing</html:code> if it encounters an empty tree.</html:p>
                    <html:p>Since an ordering is involved, we have to declare the functions for a specific
type, here <html:code>string</html:code>.  Now <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Missing</html:code> mentions that type: if lookup
fails, the exception returns the missing key.  The exception could be
eliminated using type <html:code>option</html:code> of our earlier <fr:link href="/~avsm2/fcs/focs-datatypes/" title="Datatypes and Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-datatypes/" display-uri="focs-datatypes" type="local">Datatypes lecture</fr:link>, using the
constructor <html:code>None</html:code> for failure.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/</fr:uri>
                    <fr:display-uri>focs-funarray-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-lookup/</fr:route>
                    <fr:title text="The Lookup Function">The Lookup Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Subscript
  let rec sub = function
  | Lf, _ -> raise Subscript  (* Not found *)
  | Br (v, t1, t2), k ->
      if k = 1 then v
      else if k mod 2 = 0 then
        sub (t1, k / 2)
      else
        sub (t2, k / 2)
exception Subscript
val sub : 'a tree * int -> 'a = <fun>
# let rec sub = function (* Alternative implementation *)
  | Lf, _ -> raise Subscript
  | Br (v, t1, t2), 1 -> v
  | Br (v, t1, t2), k when k mod 2 = 0 -> sub (t1, k / 2)
  | Br (v, t1, t2), k -> sub (t2, k / 2)
val sub : 'a tree * int -> 'a = <fun>]]></html:pre>
                    <html:p>Notice that we have used a new keyword <html:code>when</html:code> above, which changes
pattern clauses to be only matched if the expression evalutes to true.
This can be equivalently expressed by moving the corresponding
checks into an <html:code>if</html:code> clause on the right hand side of the <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern match</fr:link>,
but is often more readable using <html:code>when</html:code> (as above).</html:p>
                    <html:p>The lookup function <html:code>sub</html:code>, divides the subscript by 2 until 1 is
reached.  If the remainder is 0 then the function follows the left subtree,
otherwise the right.  If it reaches a leaf, it signals error by raising
<fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Subscript</html:code>.</html:p>
                    <html:p>Array access can also be understood in terms of the subscript’s binary code.
Because the subscript must be a positive integer, in binary it has a leading
one.  Discard this one and reverse the remaining bits.  Interpreting zero
as <html:em>left</html:em> and one as <html:em>right</html:em> yields the path from the root to the
subscript.</html:p>
                    <html:p>Popular literature often explains the importance of binary as being led by
hardware: because a circuit is either on or off.  The truth is almost the
opposite.  Designers of digital electronics go to a lot of trouble to suppress
the continuous behaviour that would naturally arise.  The real reason why
binary is important is its role in algorithms: an <html:code>if-then-else</html:code> decision leads
to binary branching.</html:p>
                    <html:p>Data structures, such as trees, and algorithms, such as <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link>, use binary
branching in order to reduce a cost from <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  Two is the
smallest integer divisor that achieves this reduction.  (Larger divisors are
only occasionally helpful, as in the case of B-trees, where they reduce the
constant factor.)  The simplicity of binary arithmetic compared with decimal
arithmetic is just another instance of the simplicity of algorithms based on
binary choices.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-update/</fr:uri>
                    <fr:display-uri>focs-funarray-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-update/</fr:route>
                    <fr:title text="The Update Function">The Update Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update = function
  | Lf, k, w ->
      if k = 1 then
        Br (w, Lf, Lf)
      else
        raise Subscript  (* Gap in tree *)
  | Br (v, t1, t2), k, w ->
      if k = 1 then
        Br (w, t1, t2)
      else if k mod 2 = 0 then
        Br (v, update (t1, k / 2, w), t2)
      else
        Br (v, t1, update (t2, k / 2, w))
val update : 'a tree * int * 'a -> 'a tree = <fun>]]></html:pre>
                    <html:p>The <html:code>update</html:code> function also divides the subscript repeatedly by two.  When it
reaches a value of one, it has identified the element position.  Then it
replaces the branch node by another branch with the new label.</html:p>
                    <html:p>A leaf may be replaced by a branch, extending the array, provided no
intervening nodes have to be generated.  This suffices for arrays without gaps
in their subscripting.  (The data structure can be modified to allow <html:em>sparse</html:em>
arrays, where most subscript positions are undefined.) Exception <fr:link href="/~avsm2/fcs/focs-funarray-lookup/" title="The Lookup Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/" display-uri="focs-funarray-lookup" type="local"><html:code>Subscript</html:code></fr:link>
indicates that the subscript position does not exist and cannot be created.
This use of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link> is not easily replaced by <html:code>None</html:code> and <html:code>Some</html:code>.</html:p>
                    <html:p>Note that there are two tests involving <fr:tex display="inline"><![CDATA[k=1]]></fr:tex>.  If we have reached a leaf,
it returns a branch, extending the array by one.  If we are still at a branch
node, then the effect is to update an existing array element.</html:p>
                    <html:p>A similar function can <html:em>shrink</html:em> an array by one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/</fr:uri>
                    <fr:display-uri>focs-bst-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-update/</fr:route>
                    <fr:title text="Update">Update</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update k v = function
  | Lf -> Br ((k, v), Lf, Lf)
  | Br ((a, x), t1, t2) ->
      if k < a then
        Br ((a, x), update k v t1, t2)
      else if a < k then
        Br ((a, x), t1, update k v t2)
      else (* a = k *)
        Br ((a, v), t1, t2)
val update : 'a -> 'b -> ('a * 'b) tree -> ('a * 'b) tree = <fun>]]></html:pre>
                    <html:p>This is also <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> as it copies the path only, and <html:em>not whole subtrees!</html:em></html:p>
                    <html:p>If you are familiar with the usual update operation for this sort of tree, you
may wonder whether it can be implemented in OCaml, where there is no direct way to
replace part of a data structure by something else.</html:p>
                    <html:p>The update operation is a nice piece of functional programming.  It searches
in the same manner as <fr:link href="/~avsm2/fcs/focs-bst-lookup/" title="Lookup: Seeks Left or Right" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/" display-uri="focs-bst-lookup" type="local"><html:code>lookup</html:code></fr:link>, but the recursive calls reconstruct a
new tree around the result of the update.  One subtree is updated and the
other left unchanged.  The internal representation of trees ensures that
unchanged parts of the tree are not copied, but <html:em>shared</html:em>.
Therefore, update copies only the path from the root to the new
node.  Its time and space requirements, for a reasonably balanced tree, are
both <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.</html:p>
                    <html:p>The comparison between <fr:tex display="inline"><![CDATA[b]]></fr:tex> and <fr:tex display="inline"><![CDATA[a]]></fr:tex> allows three cases:</html:p>
                    <html:ul><html:li>smaller: update the left subtree; share the right</html:li>
<html:li>greater: update the right subtree; share the left</html:li>
<html:li>equal: update the label and share both subtrees</html:li></html:ul>
                    <html:p>Note: in the function definition, <html:code>(* a = b*)</html:code> is a comment.  Comments
in OCaml are enclosed in the brackets <html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-5/</fr:uri>
                    <fr:display-uri>focs-ex-10-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-5/</fr:route>
                    <fr:title text="Exercises › An implicit infinite tree"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › An implicit infinite tree</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider the following OCaml function.</html:p>
                    <html:pre><![CDATA[let next n = [2 * n; 2 * n + 1]]]></html:pre>
                    <html:p>If we regard it as representing a tree, where the subtrees are computed from the current label, what
tree does <html:code>next 1</html:code> represent?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-4/</fr:uri>
                    <fr:display-uri>focs-ex-7-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-4/</fr:route>
                    <fr:title text="Exercises › Deleting from a search tree"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Deleting from a search tree</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Describe an algorithm for deleting an entry from a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>. Comment on the suitability of
your approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-5/</fr:uri>
                    <fr:display-uri>focs-ex-7-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-5/</fr:route>
                    <fr:title text="Exercises › Implementing deletion"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Implementing deletion</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code the delete function outlined in the previous exercise.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-1/</fr:uri>
                    <fr:display-uri>focs-ex-7-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-1/</fr:route>
                    <fr:title text="Exercises › Insertion order in search trees"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion order in search trees</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Draw the <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link> that arises from successively inserting the following pairs into the
empty tree: <html:code>("Alice", 6)</html:code>, <html:code>("Tobias", 2)</html:code>, <html:code>("Gerald", 8)</html:code>, <html:code>("Lucy", 9)</html:code>. Then repeat this
task using the order <html:code>("Gerald", 8)</html:code>, <html:code>("Alice", 6)</html:code>, <html:code>("Lucy", 9)</html:code>, <html:code>("Tobias", 2)</html:code>. Why are
results different?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-2/</fr:uri>
                    <fr:display-uri>focs-ex-7-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-2/</fr:route>
                    <fr:title text="Exercises › Insertion with collision detection"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion with collision detection</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an insertion function for <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link>. It should resemble the existing <fr:link href="/~avsm2/fcs/focs-bst-update/" title="Update" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/" display-uri="focs-bst-update" type="local"><html:code>update</html:code></fr:link>
function except that it should raise the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Collision</html:code> if the item to be inserted is already
present.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-4/</fr:uri>
                    <fr:display-uri>focs-ex-9-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-4/</fr:route>
                    <fr:title text="Exercises › Lazy binary trees"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Lazy binary trees</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>lazy binary tree</html:em> is either empty or is a branch containing a label and two lazy <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>,
possibly to infinite depth. Present an OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> to represent lazy binary trees, along with a
function that accepts a lazy binary tree and produces a lazy list that contains all of the tree’s
labels. (Taken from the exam question 2008 Paper 1 Question 5.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-7/</fr:uri>
                    <fr:display-uri>focs-ex-7-7</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-7/</fr:route>
                    <fr:title text="Exercises › Linear traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Linear traversals</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>preord</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>inord</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal-efficient/" title="Efficiently Traversing Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal-efficient/" display-uri="focs-tree-traversal-efficient" type="local"><html:code>postord</html:code></fr:link> all take linear time in the size of the
tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-6/</fr:uri>
                    <fr:display-uri>focs-ex-7-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-6/</fr:route>
                    <fr:title text="Exercises › Quadratic traversals"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Quadratic traversals</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Show that the functions <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>preorder</html:code></fr:link>, <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>postorder</html:code></fr:link> all require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time in the worst
case, where <fr:tex display="inline"><![CDATA[n]]></fr:tex> is the size of the tree.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-3/</fr:uri>
                    <fr:display-uri>focs-ex-10-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-3/</fr:route>
                    <fr:title text="Exercises › Rewriting breadth with let"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Rewriting breadth with let</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a version of the function <fr:link href="/~avsm2/fcs/focs-bfs-queues/" title="Breadth-First Tree Traversal — Using Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/" display-uri="focs-bfs-queues" type="local"><html:code>breadth</html:code></fr:link> using a nested <html:code>let</html:code> construction rather than
<html:code>match</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-8/</fr:uri>
                    <fr:display-uri>focs-ex-7-8</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-8/</fr:route>
                    <fr:title text="Exercises › Shifting a functional array"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Shifting a functional array</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a function to remove the first element from a <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional array</fr:link>. All the other elements are to
have their subscripts reduced by one. The cost of this operation should be linear in the size of the
array.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-2/</fr:uri>
                    <fr:display-uri>focs-ex-6-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-2/</fr:route>
                    <fr:title text="Exercises › Summing tree labels"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Summing tree labels</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write an OCaml function taking a binary tree labelled with integers and returning their sum.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-1/</fr:uri>
                    <fr:display-uri>focs-ex-10-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-1/</fr:route>
                    <fr:title text="Exercises › Tree-based queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Tree-based queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Suppose that we have an implementation of queues, based on <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>, such that each operation
takes logarithmic time in the worst case. Outline the advantages and drawbacks of such an
implementation compared with one presented above.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-3/</fr:uri>
                    <fr:display-uri>focs-ex-6-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-3/</fr:route>
                    <fr:title text="Exercises › What ftree builds"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › What ftree builds</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Using the <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">definition of <html:code>'a tree</html:code></fr:link> from before:</html:p>
                    <html:pre><![CDATA[type 'a tree = Lf | Br of 'a * 'a tree * 'a tree]]></html:pre>
                    <html:p>Examine the following function declaration. What does <html:code>ftree (1, n)</html:code> accomplish?</html:p>
                    <html:pre><![CDATA[let rec ftree k n =
  if n = 0 then Lf
  else Br (k, ftree (2 * k) (n - 1), ftree (2 * k + 1) (n - 1))]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-exceptions/</fr:uri>
                <fr:display-uri>focs-topic-exceptions</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-exceptions/</fr:route>
                <fr:title text="Exceptions">Exceptions</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/</fr:uri>
                    <fr:display-uri>focs-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-exceptions/</fr:route>
                    <fr:title text="Error Handling: Exceptions">Error Handling: Exceptions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>During a computation, what happens if something goes <html:em>wrong?</html:em></html:p>
                    <html:ul><html:li>Division by zero</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">Pattern matching</fr:link> failure</html:li></html:ul>
                    <html:p><html:em>Exception-handling</html:em> lets us recover gracefully.</html:p>
                    <html:ul><html:li>Raising an exception abandons the current computation.</html:li>
  <html:li>Handling the exception attempts an alternative computation.</html:li>
  <html:li>The raising and handling can be far apart in the code.</html:li>
  <html:li>Errors of <html:em>different sorts</html:em> can be handled separately.</html:li></html:ul>
                    <html:p>Exceptions are necessary because it is not always possible to tell in advance
whether or not a search will lead to a dead end or whether a numerical
calculation will encounter errors such as overflow or divide by zero. Rather
than just crashing, programs should check whether things have gone wrong, and
perhaps attempt an alternative computation (perhaps using a different algorithm
or higher precision). A number of modern languages provide exception handling.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/</fr:uri>
                    <fr:display-uri>focs-def-exception</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-exception/</fr:route>
                    <fr:title text="Exception">Exception</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An exception signals that something has gone <html:em>wrong</html:em> during a computation,
such as division by zero or pattern matching failure. Raising an exception
abandons the current computation; handling the exception attempts an alternative
computation. The raising and the handling can be far apart in the code, and
errors of <html:em>different sorts</html:em> can be handled separately.
Introduced in <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">Error Handling: Exceptions</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/</fr:uri>
                    <fr:display-uri>focs-ocaml-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ocaml-exceptions/</fr:route>
                    <fr:title text="Exceptions in OCaml">Exceptions in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Failure
exception Failure
# exception NoChange of int
exception NoChange of int
# raise Failure
Exception: Failure.]]></html:pre>
                    <html:p>Each <html:code>exception</html:code> declaration introduces a distinct sort of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link>, which can
be handled separately from others. If <fr:tex display="inline"><![CDATA[E]]></fr:tex> raises an exception, then its
evaluation has failed; <html:em>handling</html:em> an exception means evaluating another
expression and returning its value instead. One exception handler can specify
separate expressions for different sorts of exceptions.</html:p>
                    <html:p>Exception names are <html:em>constructors</html:em> of the special <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> <html:code>exn</html:code>.  This is a
peculiarity of OCaml that lets exception-handlers use <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>. Note that
exception <html:code>Failure</html:code> is just an error indication, while <html:code>NoChange n</html:code> carries
further information: the integer <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:pre><![CDATA[# try
    print_endline "pre exception";
    raise (NoChange 1);
    print_endline "post exception";
  with
    | NoChange _ ->
        print_endline "handled a NoChange exception"
Line 3, characters 5-23:
Warning 21 [nonreturning-statement]: this statement never returns (or has an unsound type.)
pre exception
handled a NoChange exception
- : unit = ()]]></html:pre>
                    <html:p>The effect of <html:code>raise &lt;expr&gt;</html:code> is to jump to the most recently-encountered
handler that matches <html:code>&lt;expr&gt;</html:code>.  The matching handler can only be found
<html:em>dynamically</html:em> (during execution); contrast with how OCaml associates occurrences
of identifiers with their matching declarations, which does not require running
the program.  A handler is introduced via the <html:code>try</html:code> keyword, which executes
the subexpression and dispatches any exceptions encountered to the corresponding
pattern match for exceptions defined in the <html:code>with</html:code> block.</html:p>
                    <html:p>This is also the first time that we have encountered the <html:code>unit</html:code> type. This
represents a type that has no values, and is used to indicate that a block
has no meaningful return value.  We will come back to this when learning more
about <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local"><html:em>imperative</html:em> programming</fr:link> later on.  For now, it is sufficient to understand
that <html:code>print_endline</html:code> will print out the argument to the console output, and return
a <html:code>unit</html:code> type.  The semicolon at the end of the expression is a convenient way to
execute sequential statements that return the <html:code>unit</html:code> type.</html:p>
                    <html:p>One criticism of OCaml’s exceptions is that—unlike the Java language—nothing
in a function declaration indicates which exceptions it might raise. One
alternative to exceptions is to instead return a value of datatype <html:code>option</html:code>.</html:p>
                    <html:pre><![CDATA[# let x = Some 1
val x : int option = Some 1
# let y = None
val y : 'a option = None
# type 'a option = None | Some of 'a
type 'a option = None | Some of 'a]]></html:pre>
                    <html:p><html:code>None</html:code> signifies an error, while <html:code>Some x</html:code> returns the solution <fr:tex display="inline"><![CDATA[x]]></fr:tex>.  This
approach looks clean, but the drawback is that many places in the code would
have to check for <html:code>None</html:code>.  Despite this, there is a builtin <html:code>option</html:code> type
in OCaml as it is so useful. We will see in later lectures how to define our
own version of <html:code>option</html:code> using polymorphic datatype definitions.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/</fr:uri>
                    <fr:display-uri>focs-bst-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-lookup/</fr:route>
                    <fr:title text="Lookup: Seeks Left or Right">Lookup: Seeks Left or Right</fr:title>
                    <fr:meta name="ocaml-deps">focs-binary-trees</fr:meta>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Missing of string
exception Missing of string
# let rec lookup b = function
  | Br ((a, x), t1, t2) ->
      if b < a then
        lookup b t1
      else if a < b then
        lookup b t2
      else
        x
  | Lf -> raise (Missing b)
val lookup : string -> (string * 'a) tree -> 'a = <fun>]]></html:pre>
                    <html:p>This has guaranteed <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> access time <html:em>if</html:em> the tree is balanced!</html:p>
                    <html:p>Lookup in the <fr:link href="/~avsm2/fcs/focs-def-binary-search-tree/" title="Binary search tree" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/" display-uri="focs-def-binary-search-tree" type="local">binary search tree</fr:link> goes to the left subtree if the desired
key is smaller than the current one and to the right if it is greater.
It raises <html:code>Missing</html:code> if it encounters an empty tree.</html:p>
                    <html:p>Since an ordering is involved, we have to declare the functions for a specific
type, here <html:code>string</html:code>.  Now <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Missing</html:code> mentions that type: if lookup
fails, the exception returns the missing key.  The exception could be
eliminated using type <html:code>option</html:code> of our earlier <fr:link href="/~avsm2/fcs/focs-datatypes/" title="Datatypes and Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-datatypes/" display-uri="focs-datatypes" type="local">Datatypes lecture</fr:link>, using the
constructor <html:code>None</html:code> for failure.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/</fr:uri>
                    <fr:display-uri>focs-change-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-exceptions/</fr:route>
                    <fr:title text="Making Change with Exceptions">Making Change with Exceptions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Change
  let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise Change
    | c::till, amt -> if amt < 0 then raise Change
                      else try c :: change (c::till) (amt - c)
                           with Change -> change till amt
exception Change
val change : int list -> int -> int list = <fun>]]></html:pre>
                    <html:p>In the <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">Lists lectures</fr:link>, we considered the problem of <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.  The greedy
algorithm presented there could not express “6 using 5 and 2” because it always
took the largest coin.  Returning <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">the list of all possible solutions</fr:link> avoids
that problem rather expensively: we only need one solution.</html:p>
                    <html:p>Using <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>, we can code a <html:em>backtracking</html:em> algorithm: one that can undo
past decisions if it comes to a dead end.  The exception <html:code>Change</html:code> is raised if
we run out of coins (with a non-zero amount) or if the amount goes negative.
We always try the largest coin, but enclose the recursive call in an exception
handler, which undoes the choice if it goes wrong.</html:p>
                    <html:p>Carefully observe how exceptions interact with <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  The exception
handler always undoes the <html:em>most recent</html:em> choice, leaving others possibly to
be undone later.  If making change really is impossible, then eventually
<html:code>exception Change</html:code> will be raised with no handler to catch it, and it
will be reported at top level.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-trace/</fr:uri>
                    <fr:display-uri>focs-change-trace</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-trace/</fr:route>
                    <fr:title text="Making Change: A Trace">Making Change: A Trace</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Here is the full execution. Observe how the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception handlers</fr:link> nest and how
they drop away once the given expression has returned a value.</html:p>
                    <fr:tex display="block"><![CDATA[\begin{aligned}
\text{change [5; 2] 6}
  \Rightarrow &\; \text{try 5::change [5; 2] 1}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 5::change [5; 2] (-4)}\\
              &\; \text{with Change -> change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{5::(change [2] 1)}\\
              &\; \text{with Change -> change [2] 6}\\
  \Rightarrow &\; \text{try 5::(try 2::change [2] (-1)}\\
              &\; \text{with Change -> change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{try 5::(change [] 1)}\\
              &\; \text{with Change -> change [2] 6} \\
  \Rightarrow &\; \text{change [2] 6} \\
  \Rightarrow &\; \text{try 2::change [2] 4}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::change [2] 2}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::(try 2::change [2] 0 }\\
              &\; \text{with Change -> change [] 2)}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::(try 2::[2]}\\
              &\; \text{with Change -> change [] 4)}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{try 2::[2; 2]}\\
              &\; \text{with Change -> change [] 6} \\
  \Rightarrow &\; \text{[2; 2; 2]}
\end{aligned}]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/</fr:uri>
                    <fr:display-uri>focs-private-references</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-private-references/</fr:route>
                    <fr:title text="Private, Persistent References">Private, Persistent References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception TooMuch of int
exception TooMuch of int
# let makeAccount initBalance =
    let balance = ref initBalance in
    let withdraw amt =
       if amt > !balance then
         raise (TooMuch (amt - !balance))
       else begin
         balance := !balance - amt;
         !balance
       end
    in
    withdraw
val makeAccount : int -> int -> int = <fun>]]></html:pre>
                    <html:p>As you may have noticed, OCaml’s programming style looks clumsy compared with
that of languages like C.  OCaml omits the defaults and abbreviations they
provide to shorten programs.  However, OCaml’s explicitness makes it ideal for
teaching the fine points of <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> and arrays.  OCaml’s references are more
flexible than those found in other languages.</html:p>
                    <html:p>The function <html:code>makeAccount</html:code> models a bank.  Calling the function with a
specified initial balance creates a new reference <html:code>balance</html:code><![CDATA[)]]> to
maintain the account balance and returns a function (<html:code>withdraw</html:code>) having
sole access to that reference.  Calling <html:code>withdraw</html:code> reduces the balance
by the specified amount and returns the new balance.  You can pay money in by
withdrawing a negative amount.  The <html:code>if</html:code>-construct prevents the account
from going overdrawn, <fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">raising an exception</fr:link>.</html:p>
                    <html:p>Look at the <fr:tex display="inline"><![CDATA[\tt  (E_1; E_2)]]></fr:tex> construct in the <html:em>else</html:em> part above.
The first expression updates the account balance and returns the trivial
value ().  The second expression, <html:code>!balance</html:code>, returns the current
balance but does not return the reference itself: that would allow
unauthorised updates.</html:p>
                    <html:p>This example is based on one by Dr A C Norman.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/</fr:uri>
                    <fr:display-uri>focs-funarray-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-lookup/</fr:route>
                    <fr:title text="The Lookup Function">The Lookup Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Subscript
  let rec sub = function
  | Lf, _ -> raise Subscript  (* Not found *)
  | Br (v, t1, t2), k ->
      if k = 1 then v
      else if k mod 2 = 0 then
        sub (t1, k / 2)
      else
        sub (t2, k / 2)
exception Subscript
val sub : 'a tree * int -> 'a = <fun>
# let rec sub = function (* Alternative implementation *)
  | Lf, _ -> raise Subscript
  | Br (v, t1, t2), 1 -> v
  | Br (v, t1, t2), k when k mod 2 = 0 -> sub (t1, k / 2)
  | Br (v, t1, t2), k -> sub (t2, k / 2)
val sub : 'a tree * int -> 'a = <fun>]]></html:pre>
                    <html:p>Notice that we have used a new keyword <html:code>when</html:code> above, which changes
pattern clauses to be only matched if the expression evalutes to true.
This can be equivalently expressed by moving the corresponding
checks into an <html:code>if</html:code> clause on the right hand side of the <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern match</fr:link>,
but is often more readable using <html:code>when</html:code> (as above).</html:p>
                    <html:p>The lookup function <html:code>sub</html:code>, divides the subscript by 2 until 1 is
reached.  If the remainder is 0 then the function follows the left subtree,
otherwise the right.  If it reaches a leaf, it signals error by raising
<fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Subscript</html:code>.</html:p>
                    <html:p>Array access can also be understood in terms of the subscript’s binary code.
Because the subscript must be a positive integer, in binary it has a leading
one.  Discard this one and reverse the remaining bits.  Interpreting zero
as <html:em>left</html:em> and one as <html:em>right</html:em> yields the path from the root to the
subscript.</html:p>
                    <html:p>Popular literature often explains the importance of binary as being led by
hardware: because a circuit is either on or off.  The truth is almost the
opposite.  Designers of digital electronics go to a lot of trouble to suppress
the continuous behaviour that would naturally arise.  The real reason why
binary is important is its role in algorithms: an <html:code>if-then-else</html:code> decision leads
to binary branching.</html:p>
                    <html:p>Data structures, such as trees, and algorithms, such as <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link>, use binary
branching in order to reduce a cost from <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  Two is the
smallest integer divisor that achieves this reduction.  (Larger divisors are
only occasionally helpful, as in the case of B-trees, where they reduce the
constant factor.)  The simplicity of binary arithmetic compared with decimal
arithmetic is just another instance of the simplicity of algorithms based on
binary choices.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-update/</fr:uri>
                    <fr:display-uri>focs-funarray-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-update/</fr:route>
                    <fr:title text="The Update Function">The Update Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update = function
  | Lf, k, w ->
      if k = 1 then
        Br (w, Lf, Lf)
      else
        raise Subscript  (* Gap in tree *)
  | Br (v, t1, t2), k, w ->
      if k = 1 then
        Br (w, t1, t2)
      else if k mod 2 = 0 then
        Br (v, update (t1, k / 2, w), t2)
      else
        Br (v, t1, update (t2, k / 2, w))
val update : 'a tree * int * 'a -> 'a tree = <fun>]]></html:pre>
                    <html:p>The <html:code>update</html:code> function also divides the subscript repeatedly by two.  When it
reaches a value of one, it has identified the element position.  Then it
replaces the branch node by another branch with the new label.</html:p>
                    <html:p>A leaf may be replaced by a branch, extending the array, provided no
intervening nodes have to be generated.  This suffices for arrays without gaps
in their subscripting.  (The data structure can be modified to allow <html:em>sparse</html:em>
arrays, where most subscript positions are undefined.) Exception <fr:link href="/~avsm2/fcs/focs-funarray-lookup/" title="The Lookup Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/" display-uri="focs-funarray-lookup" type="local"><html:code>Subscript</html:code></fr:link>
indicates that the subscript position does not exist and cannot be created.
This use of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link> is not easily replaced by <html:code>None</html:code> and <html:code>Some</html:code>.</html:p>
                    <html:p>Note that there are two tests involving <fr:tex display="inline"><![CDATA[k=1]]></fr:tex>.  If we have reached a leaf,
it returns a branch, extending the array by one.  If we are still at a branch
node, then the effect is to update an existing array element.</html:p>
                    <html:p>A similar function can <html:em>shrink</html:em> an array by one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-5/</fr:uri>
                    <fr:display-uri>focs-ex-6-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-5/</fr:route>
                    <fr:title text="Exercises › Evaluating expressions with exceptions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Evaluating expressions with exceptions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Continuing the previous exercise, write a function that evaluates an expression. If the expression
contains any variables, your function should raise an <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> indicating the variable name.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-2/</fr:uri>
                    <fr:display-uri>focs-ex-7-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-2/</fr:route>
                    <fr:title text="Exercises › Insertion with collision detection"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion with collision detection</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an insertion function for <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link>. It should resemble the existing <fr:link href="/~avsm2/fcs/focs-bst-update/" title="Update" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/" display-uri="focs-bst-update" type="local"><html:code>update</html:code></fr:link>
function except that it should raise the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Collision</html:code> if the item to be inserted is already
present.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-3/</fr:uri>
                    <fr:display-uri>focs-ex-7-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-3/</fr:route>
                    <fr:title text="Exercises › Returning the old value on collision"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Returning the old value on collision</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Continuing the previous exercise, it would be natural for exceptional <html:code>Collision</html:code> to return the
value previously stored in the dictionary. Why is that goal difficult to achieve?</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-dictionaries/</fr:uri>
                <fr:display-uri>focs-topic-dictionaries</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-dictionaries/</fr:route>
                <fr:title text="Dictionaries">Dictionaries</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstract-data-type/</fr:uri>
                    <fr:display-uri>focs-def-abstract-data-type</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-abstract-data-type/</fr:route>
                    <fr:title text="Abstract data type">Abstract data type</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent them. Before choosing the
internal representation for a data structure, you need to specify the full set of
operations. Abstract types can be declared in any modern programming language:
Java’s <html:em>objects</html:em> serve this role, as do OCaml’s modules.
Introduced in <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">Dictionaries</fr:link>, and applied to
<fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local">queues</fr:link> and <fr:link href="/~avsm2/fcs/focs-stacks/" title="Another Abstract Data Type: Stacks" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/" display-uri="focs-stacks" type="local">stacks</fr:link> later on.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-arrays/</fr:uri>
                    <fr:display-uri>focs-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-arrays/</fr:route>
                    <fr:title text="Arrays">Arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>A conventional array is an indexed storage area.
  <html:ul><html:li>It is updated <html:em>in place</html:em> by the command <html:code>a.(k) &lt;- x</html:code></html:li>
  <html:li>The concept is inherently <html:em>imperative</html:em>.</html:li></html:ul></html:li>
<html:li>A <html:em>functional array</html:em> is a finite map from integers to data.
  <html:ul><html:li>Updating implies <html:em>copying</html:em> to return <html:code>update(A, k, x)</html:code></html:li>
  <html:li>The new array equals <html:code>A</html:code> except that <html:code>A.(k) = x</html:code>.</html:li></html:ul></html:li>
<html:li>Can we do updates efficiently?</html:li></html:ul>
                    <html:p>The elements of a list can only be reached by counting from the front.
Elements of a tree are reached by following a path from the root.  An
<html:em>array</html:em> hides such structural matters; its elements are uniformly
designated by number.  Immediate access to arbitrary parts of a data structure
is called <html:em>random access</html:em>.</html:p>
                    <html:p>Arrays are the dominant data structure in conventional programming languages.
The ingenious use of arrays is the key to many of the great classical
algorithms, such as Hoare’s original <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link> (the partition step) and
Warshall’s transitive-closure algorithm.</html:p>
                    <html:p>The drawback is that subscripting is a chief cause of programmer error.  That
is why arrays play little role in this introductory course.</html:p>
                    <html:p>Functional arrays are described below in order to illustrate another way of
using trees to organise data.  Here is a summary of basic dictionary data
structures in order of decreasing generality and increasing efficiency:</html:p>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link>: Most general, needing only equality on keys, but inefficient: linear time.</html:li>
<html:li>Binary search: Needs an ordering on keys.  Logarithmic access time in the average case, but our <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link> are linear in the worst case.</html:li>
<html:li>Array subscripting: Least general, requiring keys to be integers, but even worst-case time is logarithmic.</html:li></html:ul>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/</fr:uri>
                    <fr:display-uri>focs-bst</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst/</fr:route>
                    <fr:title text="Binary Search Trees">Binary Search Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>dictionary</html:em> associates <html:em>values</html:em> (here, numbers) with <html:em>keys</html:em>.</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifkdrvs6ut5buyf724655gdcinx637uevqiaejsmb2jgu36gaf4wq.svg" />
                    </html:figure>
                    <html:p>Binary search trees are an important application of <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>.  They work
for keys that have a total ordering, such as strings.  Each branch of the tree
carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree holds smaller keys; the right
subtree holds greater keys.  If the tree remains reasonably balanced, then
update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  These times
hold in the average case; given random data, the tree is likely to remain
balanced.</html:p>
                    <html:p>At a given node, all keys in the left subtree are smaller (or equal) while all
trees in the right subtree are greater.</html:p>
                    <html:p>An unbalanced tree has a linear access time in the worst case.  Examples
include building a tree by repeated insertions of elements in increasing or
decreasing order; there is a close resemblance to <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>.  Building a binary
search tree, then converting it to <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">inorder</fr:link>, yields a sorting algorithm called
<html:em>treesort</html:em>.</html:p>
                    <html:p>Self-balancing trees, such as Red-Black trees, attain <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> in the worst
case.  They are complicated to implement.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/</fr:uri>
                    <fr:display-uri>focs-def-binary-search-tree</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-binary-search-tree/</fr:route>
                    <fr:title text="Binary search tree">Binary search tree</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A binary search tree works for keys that have a total ordering, such as
strings. Each branch of the tree carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree
holds smaller keys and its right subtree holds greater keys. If the tree remains
reasonably balanced, then update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of
size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary Search Trees</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/</fr:uri>
                    <fr:display-uri>focs-dictionary-adt</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-dictionary-adt/</fr:route>
                    <fr:title text="Dictionaries">Dictionaries</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>lookup: find an item in the dictionary</html:li>
<html:li>update (insert): replace (store) an item in the dictionary</html:li>
<html:li>delete: remove an item from the dictionary</html:li>
<html:li>empty: the null dictionary</html:li>
<html:li>Missing: <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> for errors in <html:code>lookup</html:code> and <html:code>delete</html:code></html:li></html:ul>
                    <html:p>Ideally, an <html:em>abstract type</html:em> should provide these operations and hide the internal data structures.</html:p>
                    <html:p>A dictionary attaches values to identifiers, called “keys”.  Before choosing
the internal representation for a data structure, you need to specify the full
set of operations. In fact, here we only consider <html:code>update</html:code> (associating a
value with an identifier) and <html:code>lookup</html:code> (retrieving such a value). Deletion
is more difficult and would limit our choices. Some applications may need
additional operations, such as <html:code>merge</html:code> (combining two dictionaries). We
shall see that update can be done efficiently in a functional style, without
excessive copying.</html:p>
                    <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent dictionaries. Abstract
types can be declared in any modern programming language. Java’s <html:em>objects</html:em>
serve this role, as do OCaml’s modules. This course does not cover modules, and we
simply declare the dictionary operations individually.</html:p>
                    <html:p>An <html:em>association list</html:em> (a list of pairs) is the simplest dictionary representation.
Lookup is by <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link>, and therefore slow: <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>. Association lists are
only usable if there are few keys in use. However, they are general in that the
keys do not need a concept of ordering, only equality.</html:p>
                    <html:pre><![CDATA[# exception Missing
exception Missing
# let rec lookup a = function
  | [] -> raise Missing
  | (x, y) :: pairs ->
      if a = x then y
      else lookup a pairs
val lookup : 'a -> ('a * 'b) list -> 'b = <fun>
# let update (l, b, y) = (b, y) :: l
val update : ('a * 'b) list * 'a * 'b -> ('a * 'b) list = <fun>]]></html:pre>
                    <html:p>To enter a new <html:code>(key, value)</html:code> pair, simply “cons” it to the list with <html:code>update</html:code>.
This takes constant time, which is the best we could hope for.  But the space
requirement is huge: linear in the number of updates, not in the number of
distinct keys. Obsolete entries are never deleted: that would require first
finding them, increasing the update time from <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/</fr:uri>
                    <fr:display-uri>focs-bst-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-lookup/</fr:route>
                    <fr:title text="Lookup: Seeks Left or Right">Lookup: Seeks Left or Right</fr:title>
                    <fr:meta name="ocaml-deps">focs-binary-trees</fr:meta>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Missing of string
exception Missing of string
# let rec lookup b = function
  | Br ((a, x), t1, t2) ->
      if b < a then
        lookup b t1
      else if a < b then
        lookup b t2
      else
        x
  | Lf -> raise (Missing b)
val lookup : string -> (string * 'a) tree -> 'a = <fun>]]></html:pre>
                    <html:p>This has guaranteed <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> access time <html:em>if</html:em> the tree is balanced!</html:p>
                    <html:p>Lookup in the <fr:link href="/~avsm2/fcs/focs-def-binary-search-tree/" title="Binary search tree" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-binary-search-tree/" display-uri="focs-def-binary-search-tree" type="local">binary search tree</fr:link> goes to the left subtree if the desired
key is smaller than the current one and to the right if it is greater.
It raises <html:code>Missing</html:code> if it encounters an empty tree.</html:p>
                    <html:p>Since an ordering is involved, we have to declare the functions for a specific
type, here <html:code>string</html:code>.  Now <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Missing</html:code> mentions that type: if lookup
fails, the exception returns the missing key.  The exception could be
eliminated using type <html:code>option</html:code> of our earlier <fr:link href="/~avsm2/fcs/focs-datatypes/" title="Datatypes and Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-datatypes/" display-uri="focs-datatypes" type="local">Datatypes lecture</fr:link>, using the
constructor <html:code>None</html:code> for failure.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/</fr:uri>
                    <fr:display-uri>focs-bst-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst-update/</fr:route>
                    <fr:title text="Update">Update</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update k v = function
  | Lf -> Br ((k, v), Lf, Lf)
  | Br ((a, x), t1, t2) ->
      if k < a then
        Br ((a, x), update k v t1, t2)
      else if a < k then
        Br ((a, x), t1, update k v t2)
      else (* a = k *)
        Br ((a, v), t1, t2)
val update : 'a -> 'b -> ('a * 'b) tree -> ('a * 'b) tree = <fun>]]></html:pre>
                    <html:p>This is also <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> as it copies the path only, and <html:em>not whole subtrees!</html:em></html:p>
                    <html:p>If you are familiar with the usual update operation for this sort of tree, you
may wonder whether it can be implemented in OCaml, where there is no direct way to
replace part of a data structure by something else.</html:p>
                    <html:p>The update operation is a nice piece of functional programming.  It searches
in the same manner as <fr:link href="/~avsm2/fcs/focs-bst-lookup/" title="Lookup: Seeks Left or Right" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-lookup/" display-uri="focs-bst-lookup" type="local"><html:code>lookup</html:code></fr:link>, but the recursive calls reconstruct a
new tree around the result of the update.  One subtree is updated and the
other left unchanged.  The internal representation of trees ensures that
unchanged parts of the tree are not copied, but <html:em>shared</html:em>.
Therefore, update copies only the path from the root to the new
node.  Its time and space requirements, for a reasonably balanced tree, are
both <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.</html:p>
                    <html:p>The comparison between <fr:tex display="inline"><![CDATA[b]]></fr:tex> and <fr:tex display="inline"><![CDATA[a]]></fr:tex> allows three cases:</html:p>
                    <html:ul><html:li>smaller: update the left subtree; share the right</html:li>
<html:li>greater: update the right subtree; share the left</html:li>
<html:li>equal: update the label and share both subtrees</html:li></html:ul>
                    <html:p>Note: in the function definition, <html:code>(* a = b*)</html:code> is a comment.  Comments
in OCaml are enclosed in the brackets <html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-4/</fr:uri>
                    <fr:display-uri>focs-ex-7-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-4/</fr:route>
                    <fr:title text="Exercises › Deleting from a search tree"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Deleting from a search tree</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Describe an algorithm for deleting an entry from a <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link>. Comment on the suitability of
your approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-5/</fr:uri>
                    <fr:display-uri>focs-ex-7-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-5/</fr:route>
                    <fr:title text="Exercises › Implementing deletion"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Implementing deletion</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code the delete function outlined in the previous exercise.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-1/</fr:uri>
                    <fr:display-uri>focs-ex-7-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-1/</fr:route>
                    <fr:title text="Exercises › Insertion order in search trees"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion order in search trees</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Draw the <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search tree</fr:link> that arises from successively inserting the following pairs into the
empty tree: <html:code>("Alice", 6)</html:code>, <html:code>("Tobias", 2)</html:code>, <html:code>("Gerald", 8)</html:code>, <html:code>("Lucy", 9)</html:code>. Then repeat this
task using the order <html:code>("Gerald", 8)</html:code>, <html:code>("Alice", 6)</html:code>, <html:code>("Lucy", 9)</html:code>, <html:code>("Tobias", 2)</html:code>. Why are
results different?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-2/</fr:uri>
                    <fr:display-uri>focs-ex-7-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-2/</fr:route>
                    <fr:title text="Exercises › Insertion with collision detection"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Insertion with collision detection</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an insertion function for <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link>. It should resemble the existing <fr:link href="/~avsm2/fcs/focs-bst-update/" title="Update" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst-update/" display-uri="focs-bst-update" type="local"><html:code>update</html:code></fr:link>
function except that it should raise the <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Collision</html:code> if the item to be inserted is already
present.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-3/</fr:uri>
                    <fr:display-uri>focs-ex-7-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-3/</fr:route>
                    <fr:title text="Exercises › Returning the old value on collision"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Returning the old value on collision</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Continuing the previous exercise, it would be natural for exceptional <html:code>Collision</html:code> to return the
value previously stored in the dictionary. Why is that goal difficult to achieve?</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-arrays/</fr:uri>
                <fr:display-uri>focs-topic-arrays</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-arrays/</fr:route>
                <fr:title text="Arrays">Arrays</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-examples/</fr:uri>
                    <fr:display-uri>focs-array-examples</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-array-examples/</fr:route>
                    <fr:title text="Array Examples">Array Examples</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>In the following session, the identifier <html:code>ar</html:code> is bound to an array of 20 elements, which
are initially set to the squares of their subscripts.  The array’s third
element (which actually has subscript 2) is inspected and found to be four. The
second call to <html:code>Array.get</html:code> supplies a subscript that is out of range, so OCaml
rejects it.</html:p>
                    <html:pre><![CDATA[# let ar = Array.init 20 (fun i -> i * i)
val ar : int array =
  [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
    289; 324; 361|]
# Array.get ar 2
- : int = 4
# Array.get ar 20
Exception: Invalid_argument "index out of bounds".
# Array.set ar 2 33; ar
- : int array =
[|0; 1; 33; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
  289; 324; 361|]]]></html:pre>
                    <html:p>By calling <html:code>Array.set</html:code>, we then modify the element with subscript 2. Note
however that we cannot modify the array’s length. If we outgrow the array, we
have to create a new one, copy the data into it, and then forget the old array.
Typically the new array would be double the size of the old one, so that the
cost of copying is insignificant.</html:p>
                    <html:p>OCaml provides numerous operators for modifying, computing over and searching in
arrays. Many are analogous to <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">functions on lists</fr:link>. For example,
<html:code>Array.exists</html:code> takes a boolean-valued function and returns <html:code>true</html:code> if an
array element satisfies it.</html:p>
                    <html:pre><![CDATA[# Array.exists (fun i -> i > 200) ar
- : bool = true
# Array.exists (fun i -> i < 0) ar
- : bool = false]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-arrays/</fr:uri>
                    <fr:display-uri>focs-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-arrays/</fr:route>
                    <fr:title text="Arrays">Arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>A conventional array is an indexed storage area.
  <html:ul><html:li>It is updated <html:em>in place</html:em> by the command <html:code>a.(k) &lt;- x</html:code></html:li>
  <html:li>The concept is inherently <html:em>imperative</html:em>.</html:li></html:ul></html:li>
<html:li>A <html:em>functional array</html:em> is a finite map from integers to data.
  <html:ul><html:li>Updating implies <html:em>copying</html:em> to return <html:code>update(A, k, x)</html:code></html:li>
  <html:li>The new array equals <html:code>A</html:code> except that <html:code>A.(k) = x</html:code>.</html:li></html:ul></html:li>
<html:li>Can we do updates efficiently?</html:li></html:ul>
                    <html:p>The elements of a list can only be reached by counting from the front.
Elements of a tree are reached by following a path from the root.  An
<html:em>array</html:em> hides such structural matters; its elements are uniformly
designated by number.  Immediate access to arbitrary parts of a data structure
is called <html:em>random access</html:em>.</html:p>
                    <html:p>Arrays are the dominant data structure in conventional programming languages.
The ingenious use of arrays is the key to many of the great classical
algorithms, such as Hoare’s original <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link> (the partition step) and
Warshall’s transitive-closure algorithm.</html:p>
                    <html:p>The drawback is that subscripting is a chief cause of programmer error.  That
is why arrays play little role in this introductory course.</html:p>
                    <html:p>Functional arrays are described below in order to illustrate another way of
using trees to organise data.  Here is a summary of basic dictionary data
structures in order of decreasing generality and increasing efficiency:</html:p>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link>: Most general, needing only equality on keys, but inefficient: linear time.</html:li>
<html:li>Binary search: Needs an ordering on keys.  Logarithmic access time in the average case, but our <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link> are linear in the worst case.</html:li>
<html:li>Array subscripting: Least general, requiring keys to be integers, but even worst-case time is logarithmic.</html:li></html:ul>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/</fr:uri>
                    <fr:display-uri>focs-functional-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-arrays/</fr:route>
                    <fr:title text="Functional Arrays as Binary Trees">Functional Arrays as Binary Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The path to element <fr:tex display="inline"><![CDATA[i]]></fr:tex> follows the <html:em>binary code</html:em> for <fr:tex display="inline"><![CDATA[i]]></fr:tex> (its “subscript”).</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifetc2v73r7qxnzo6bthiblab2tezbaqvmovq7e4q6vgdl5ewr3wi.svg" />
                    </html:figure>
                    <html:p>This simple representation (credited to W. Braun) ensures that the tree is
balanced.  Complexity of access is always <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>, which is optimal.  For
actual running time, access to conventional arrays is much faster: it requires
only a few hardware instructions.  Array access is often taken to be <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>,
which (as always) presumes that hardware limits are never exceeded.</html:p>
                    <html:p>The lower bound for array subscripts (or “indices”) is one.  The upper bound starts at zero
(which signifies the empty array) and can grow without limit.  Inspection of
the diagram above should make it clear that these trees are always balanced:
the left subtree can have at most one node more than the right subtree,
recursively all the way down.  (This assumes that the array is defined for
subscripts <fr:tex display="inline"><![CDATA[1\ldots  n]]></fr:tex> with no gaps; an array defined only for odd numbers, for
example, would obviously be unbalanced.)</html:p>
                    <html:p>The numbers in the diagram above are not the labels of branch nodes, but
indicate the positions of array elements. For example, the label corresponding
to <fr:tex display="inline"><![CDATA[A[2]]]></fr:tex> is at the position shown. The nodes of a functional array are
labelled with the data we want to store, not with these integers.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/</fr:uri>
                    <fr:display-uri>focs-array-primitives</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-array-primitives/</fr:route>
                    <fr:title text="OCaml Primitives for Arrays">OCaml Primitives for Arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# [|"a"; "b"; "c"|] (* allocate a fresh string array *)
- : string array = [|"a"; "b"; "c"|]
# Array.make 3 'a'   (* array[3] with cell containing 'a' *)
- : char array = [|'a'; 'a'; 'a'|]
# let aa = Array.init 5 (fun i -> i * 10) (* array[5] initialised to (fun i) *)
val aa : int array = [|0; 10; 20; 30; 40|]
# Array.get aa 3  (* retrieve the 4th cell in the array *)
- : int = 30
# Array.set aa 3 42 (* set the 4th cell's value to 42 *)
- : unit = ()]]></html:pre>
                    <html:p>There are many other array operations in the <html:code>Array</html:code> module in the OCaml standard
library.</html:p>
                    <html:pre><![CDATA[# Array.make
- : int -> 'a -> 'a array = <fun>
# Array.init
- : int -> (int -> 'a) -> 'a array = <fun>
# Array.get
- : 'a array -> int -> 'a = <fun>
# Array.set
- : 'a array -> int -> 'a -> unit = <fun>]]></html:pre>
                    <html:p>OCaml arrays are like <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> that hold several elements instead of one.  The
elements of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element array are designated by the integers from 0
to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.  The <fr:tex display="inline"><![CDATA[i]]></fr:tex>th array element is usually written <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.
If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is a type then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>array</html:code> is the
type of arrays (of any size) with elements from <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.</html:p>
                    <html:p>Calling <html:code>Array.init n f</html:code> creates an array of the size specified in <fr:tex display="inline"><![CDATA[n]]></fr:tex>
by function <fr:tex display="inline"><![CDATA[f]]></fr:tex>.  Initially, element <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex> holds the value of <fr:tex display="inline"><![CDATA[f(i)]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.
Like <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local"><html:code>ref</html:code></fr:link>, it allocates mutable storage to hold the specified values.</html:p>
                    <html:p>Calling <html:code>Array.get A i</html:code> returns the contents of <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.</html:p>
                    <html:p>Calling <html:code>Array.set A i E</html:code> modifies the array <fr:tex display="inline"><![CDATA[A]]></fr:tex> by storing the
value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as the new contents of <fr:tex display="inline"><![CDATA[A[i]]]></fr:tex>; it returns <html:code>()</html:code> as its value.</html:p>
                    <html:p>OCaml’s arrays are much safer than C’s. In C, an array is nothing more than an
address indicating the start of a storage area. Nothing indicates the size of
the area.  Therefore C programs are vulnerable to <html:em>buffer overrun attacks:</html:em> an
attacker sends more data than the receiving program expects, overrunning the
area of storage set aside to hold it. The attack eventually overwrites the
program itself, replacing it with code controlled by the attacker.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-comparison/</fr:uri>
                    <fr:display-uri>focs-references-comparison</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references-comparison/</fr:route>
                    <fr:title text="References: OCaml vs conventional languages">References: OCaml vs conventional languages</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>We must write <html:code>!p</html:code> to get the <html:em>contents</html:em> of <html:code>p</html:code></html:li>
  <html:li>We write just <html:code>p</html:code> for the <html:em>address</html:em> of <html:code>p</html:code></html:li>
  <html:li>We can store private <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference cells</fr:link> (like <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>balance</html:code></fr:link>) in functions—analogous to elements of <html:em>object-oriented programming</html:em></html:li>
  <html:li>OCaml’s assignment syntax is <fr:tex display="inline"><![CDATA[\tt  V \, := \, E]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[V]]></fr:tex> = <fr:tex display="inline"><![CDATA[E]]></fr:tex></html:li>
  <html:li>OCaml has few control structures: <fr:link href="/~avsm2/fcs/focs-while/" title="Iteration: the while command" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/" display-uri="focs-while" type="local"><html:code>while</html:code></fr:link>, <html:code>match</html:code>, <html:code>if</html:code> and <html:code>for</html:code> (the latter is not covered in this course)</html:li>
  <html:li>OCaml has syntax for updating an array via the <html:code>a.(i) &lt;- v</html:code> syntax which is the same as <fr:link href="/~avsm2/fcs/focs-array-primitives/" title="OCaml Primitives for Arrays" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/" display-uri="focs-array-primitives" type="local"><html:code>Array.set a i v</html:code></fr:link>.</html:li></html:ul>
                    <html:p>Conventional syntax for variables and assignments has hardly changed since
Fortran, the first high-level language. In conventional languages,
virtually all variables can be updated.  We declare something like
<html:code>p: int</html:code>, mentioning no reference type even if the language provides
them.  If we do not specify an initial value, we may get whatever bits were
previously at that address.  Illegal values arising from uninitialised
variables can cause errors that are almost impossible to diagnose.</html:p>
                    <html:p>Dereferencing operators (like OCaml’s <html:code>!</html:code>) are especially unpopular, because
they clutter the program text. Virtually all programming languages make dereferencing
implicit (that is, automatic).</html:p>
                    <html:p>It is generally accepted these days that a two-dimensional array <fr:tex display="inline"><![CDATA[A]]></fr:tex> is nothing
but an array of arrays.  An assignment to such an array is typically written
something like <fr:tex display="inline"><![CDATA[A[i,j] {:=} x]]></fr:tex>; in C, the syntax is <html:code>A[i][j] = x</html:code>. Higher
dimensions are treated analogously.  The corresponding OCaml code can either
declare an array of arrays, or use the <html:code>A.(i)</html:code> syntax to calculate the linear
offset into a single array.</html:p>
                    <html:p>You can use the constructs we have learnt to easily create linked (mutable) lists as
an alternative to arrays.</html:p>
                    <html:pre><![CDATA[# type 'a mlist =
  | Nil
  | Cons of 'a * 'a mlist ref
type 'a mlist = Nil | Cons of 'a * 'a mlist ref]]></html:pre>
                    <html:p>It is worth mentioning that OCaml’s references fully suffice for coding the sort of linked data structures
taught in algorithms courses, and is illustrated in the figure above. The
programming style is a little different from the usual, but the principles are
the same.  OCaml also provides comprehensive input/output primitives for various
types of file and operating system.</html:p>
                    <html:p>OCaml’s system of modules include <html:em>structures,</html:em> which can be seen as encapsulated
groups of declarations, and <html:em>signatures,</html:em> which are specifications of
structures listing the name and type of each component.  Finally, there are
<html:em>functors,</html:em> which are analogous to functions that combine a number of argument
structures, and which can be used to plug program components together. These
primitives are useful for managing large programming projects.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/</fr:uri>
                    <fr:display-uri>focs-funarray-lookup</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-lookup/</fr:route>
                    <fr:title text="The Lookup Function">The Lookup Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Subscript
  let rec sub = function
  | Lf, _ -> raise Subscript  (* Not found *)
  | Br (v, t1, t2), k ->
      if k = 1 then v
      else if k mod 2 = 0 then
        sub (t1, k / 2)
      else
        sub (t2, k / 2)
exception Subscript
val sub : 'a tree * int -> 'a = <fun>
# let rec sub = function (* Alternative implementation *)
  | Lf, _ -> raise Subscript
  | Br (v, t1, t2), 1 -> v
  | Br (v, t1, t2), k when k mod 2 = 0 -> sub (t1, k / 2)
  | Br (v, t1, t2), k -> sub (t2, k / 2)
val sub : 'a tree * int -> 'a = <fun>]]></html:pre>
                    <html:p>Notice that we have used a new keyword <html:code>when</html:code> above, which changes
pattern clauses to be only matched if the expression evalutes to true.
This can be equivalently expressed by moving the corresponding
checks into an <html:code>if</html:code> clause on the right hand side of the <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern match</fr:link>,
but is often more readable using <html:code>when</html:code> (as above).</html:p>
                    <html:p>The lookup function <html:code>sub</html:code>, divides the subscript by 2 until 1 is
reached.  If the remainder is 0 then the function follows the left subtree,
otherwise the right.  If it reaches a leaf, it signals error by raising
<fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Subscript</html:code>.</html:p>
                    <html:p>Array access can also be understood in terms of the subscript’s binary code.
Because the subscript must be a positive integer, in binary it has a leading
one.  Discard this one and reverse the remaining bits.  Interpreting zero
as <html:em>left</html:em> and one as <html:em>right</html:em> yields the path from the root to the
subscript.</html:p>
                    <html:p>Popular literature often explains the importance of binary as being led by
hardware: because a circuit is either on or off.  The truth is almost the
opposite.  Designers of digital electronics go to a lot of trouble to suppress
the continuous behaviour that would naturally arise.  The real reason why
binary is important is its role in algorithms: an <html:code>if-then-else</html:code> decision leads
to binary branching.</html:p>
                    <html:p>Data structures, such as trees, and algorithms, such as <fr:link href="/~avsm2/fcs/focs-merge-sort/" title="Top-down Merge sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-merge-sort/" display-uri="focs-merge-sort" type="local">mergesort</fr:link>, use binary
branching in order to reduce a cost from <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex>.  Two is the
smallest integer divisor that achieves this reduction.  (Larger divisors are
only occasionally helpful, as in the case of B-trees, where they reduce the
constant factor.)  The simplicity of binary arithmetic compared with decimal
arithmetic is just another instance of the simplicity of algorithms based on
binary choices.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-update/</fr:uri>
                    <fr:display-uri>focs-funarray-update</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-funarray-update/</fr:route>
                    <fr:title text="The Update Function">The Update Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec update = function
  | Lf, k, w ->
      if k = 1 then
        Br (w, Lf, Lf)
      else
        raise Subscript  (* Gap in tree *)
  | Br (v, t1, t2), k, w ->
      if k = 1 then
        Br (w, t1, t2)
      else if k mod 2 = 0 then
        Br (v, update (t1, k / 2, w), t2)
      else
        Br (v, t1, update (t2, k / 2, w))
val update : 'a tree * int * 'a -> 'a tree = <fun>]]></html:pre>
                    <html:p>The <html:code>update</html:code> function also divides the subscript repeatedly by two.  When it
reaches a value of one, it has identified the element position.  Then it
replaces the branch node by another branch with the new label.</html:p>
                    <html:p>A leaf may be replaced by a branch, extending the array, provided no
intervening nodes have to be generated.  This suffices for arrays without gaps
in their subscripting.  (The data structure can be modified to allow <html:em>sparse</html:em>
arrays, where most subscript positions are undefined.) Exception <fr:link href="/~avsm2/fcs/focs-funarray-lookup/" title="The Lookup Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-funarray-lookup/" display-uri="focs-funarray-lookup" type="local"><html:code>Subscript</html:code></fr:link>
indicates that the subscript position does not exist and cannot be created.
This use of <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link> is not easily replaced by <html:code>None</html:code> and <html:code>Some</html:code>.</html:p>
                    <html:p>Note that there are two tests involving <fr:tex display="inline"><![CDATA[k=1]]></fr:tex>.  If we have reached a leaf,
it returns a branch, extending the array by one.  If we are still at a branch
node, then the effect is to update an existing array element.</html:p>
                    <html:p>A similar function can <html:em>shrink</html:em> an array by one.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-2/</fr:uri>
                    <fr:display-uri>focs-ex-10-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-2/</fr:route>
                    <fr:title text="Exercises › Array-based circular queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Array-based circular queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The traditional way to implement queues uses a fixed-length array. Two indices into the array
indicate the start and end of the queue, which wraps around from the end of the array to the start.
How appropriate is such a data structure for implementing <fr:link href="/~avsm2/fcs/focs-bfs-dfs/" title="Breadth-First v Depth-First Tree Traversal" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/" display-uri="focs-bfs-dfs" type="local">breadth-first search</fr:link>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-5/</fr:uri>
                    <fr:display-uri>focs-ex-11-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-5/</fr:route>
                    <fr:title text="Exercises › Matrix operations on arrays"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Matrix operations on arrays</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Arrays of multiple dimensions are represented in OCaml by arrays of arrays. Write functions to
(a) create an <fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> identity matrix, given <fr:tex display="inline"><![CDATA[n]]></fr:tex>, and
(b) to <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local">transpose</fr:link> an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix. Identity matrices have the following form:</html:p>
                    <fr:tex display="block"><![CDATA[
\left ( {
\begin {array}{cccc}
   1 & 0 &  \cdots   & 0  \\
   0 & 1 &  \cdots   & 0  \\
    \vdots   &  \vdots   &  \ddots   &  \vdots    \\
   0 & 0 &  \cdots   & 1  \\
 \end {array}
 } \right )
]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7-8/</fr:uri>
                    <fr:display-uri>focs-ex-7-8</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-7-8/</fr:route>
                    <fr:title text="Exercises › Shifting a functional array"><fr:link href="/~avsm2/fcs/focs-ex-7/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-7/" display-uri="focs-ex-7" type="local">Exercises</fr:link> › Shifting a functional array</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a function to remove the first element from a <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional array</fr:link>. All the other elements are to
have their subscripts reduced by one. The cost of this operation should be linear in the size of the
array.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-higher-order-functions/</fr:uri>
                <fr:display-uri>focs-topic-higher-order-functions</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-higher-order-functions/</fr:route>
                <fr:title text="Higher order functions">Higher order functions</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-applications/</fr:uri>
                    <fr:display-uri>focs-predicate-applications</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-applications/</fr:route>
                    <fr:title text="Applications of the Predicate Functionals">Applications of the Predicate Functionals</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let member y xs =
    exists (fun x -> x=y) xs
val member : 'a -> 'a list -> bool = <fun>
# let inter xs ys =
    filter (fun x -> member x ys) xs
val inter : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Testing whether two lists have no common elements</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let disjoint xs ys =
    all (fun x -> all (fun y -> x<>y) ys) xs
val disjoint : 'a list -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The Lists lecture presented the function <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link>, which tests whether a
specified value can be found as a list element, and <html:code>inter</html:code>, which returns the
“intersection” of two lists: the list of elements they have in common.</html:p>
                    <html:p>But remember: the purpose of list <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> is not to replace the
declarations of popular functions, which probably are available already.  It is
to eliminate the need for separate declarations of ad-hoc functions.  When they
are nested, like the calls to <html:code>all</html:code> in <html:code>disjoint</html:code> above, the
inner functions are almost certainly one-offs, not worth declaring separately.</html:p>
                    <html:p>Our primitives themselves can be seen as a programming language.  Part of the
task of programming is to extend our programming language with notation for
solving the problem at hand.  The levels of notation that we define should
correspond to natural <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">levels of abstraction</fr:link> in the problem domain.</html:p>
                    <html:p>Historical Note:
Alonzo Church’s <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus gave a simple syntax, <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-notation,
for expressing functions.  It is the direct precursor of OCaml’s
<html:code>fun</html:code>-notation.  It was soon shown that his system was equivalent in
computational power to Turing machines, and <html:em>Church’s thesis</html:em> states that
this defines precisely the set of functions that can be computed effectively.</html:p>
                    <html:p>The <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus had a tremendous influence on the design of functional
programming languages.  McCarthy’s Lisp was something of a false start; it
interpreted variable binding incorrectly, an error that stood for some 20
years.  But in 1966, Peter Landin (of Queen Mary College, University of London)
sketched out the main features of functional languages.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/</fr:uri>
                    <fr:display-uri>focs-currying</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-currying/</fr:route>
                    <fr:title text="Curried Functions">Curried Functions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>curried function</html:em> returns another function as its result. We use
the string concetenation operator <html:code>(^)</html:code> to illustrate how this works.</html:p>
                    <html:pre><![CDATA[# (^)
- : string -> string -> string = <fun>
# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let promote = prefix "Senior "
val promote : string -> string = <fun>
# prefix "Junior " "Professor"
- : string = "Junior Professor"
# promote "Professor"
- : string = "Senior Professor"]]></html:pre>
                    <html:p>A short form for the definition of <html:code>prefix</html:code> is simply to pass multiple
arguments to the function definition.  The following two definitions
are equivalent in OCaml:</html:p>
                    <html:pre><![CDATA[# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>]]></html:pre>
                    <html:p>Currying is the technique of expressing a function taking multiple arguments as nested functions, each taking a single argument.
The <html:code>fun</html:code>-notation lets us package <html:code>n*2</html:code> as the function
<html:code>fun n -&gt; n * 2</html:code>, but what if there are several variables, as in
<html:code>fun n -&gt; n * 2 + k</html:code>?  A function of two arguments could be coded using
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> on pairs, writing <html:code>fun (n, k) -&gt; n * 2 + k</html:code>.</html:p>
                    <html:p>Currying is an alternative, where we <html:em>nest</html:em> the <html:code>fun</html:code>-notation:</html:p>
                    <html:pre><![CDATA[# fun k -> fun n -> n * 2 + k
- : int -> int -> int = <fun>]]></html:pre>
                    <html:p>Applying this curried function to the argument 1 yields another function, in which <html:code>k</html:code> has been replaced by 1:</html:p>
                    <html:pre><![CDATA[# let fn = fun k -> fun n -> n * 2 + k
val fn : int -> int -> int = <fun>
# let fn' = fn 1 (* n * 2 + 1 *)
val fn' : int -> int = <fun>
# fn' 3  (* 3 * 2 + 1 *)
- : int = 7]]></html:pre>
                    <html:p>And this function, when applied to 3, yields the result 7. The two arguments are supplied one after another.</html:p>
                    <html:p>The example on the slide is similar but refers to the expression <html:code>a^b</html:code>,
where <html:code>^</html:code> is the infix operator for string concatenation. Function <html:code>promote</html:code> binds the first argument of <html:code>prefix</html:code> to
<html:code>"Professor"</html:code>; the resulting function prefixes that title
to any string to which it is applied.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/</fr:uri>
                    <fr:display-uri>focs-def-currying</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-currying/</fr:route>
                    <fr:title text="Currying">Currying</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Currying is the technique of expressing a function taking multiple arguments
as nested functions, each taking a single argument. A <html:em>curried function</html:em>
returns another function as its result, so the arguments are supplied one after
another.
Introduced in <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Curried Functions</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/</fr:uri>
                    <fr:display-uri>focs-transpose</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-transpose/</fr:route>
                    <fr:title text="Example: Matrix Transpose">Example: Matrix Transpose</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {pmatrix}
           a   & b & c \\
           d   & e & f
   \end {pmatrix}^T =
   \begin {pmatrix}
        a & d     \\
        b & e     \\
        c & f
\end {pmatrix}
]]></fr:tex>
                    <html:pre><![CDATA[# let rec transp = function
    | []::_ -> []
    | rows -> (map List.hd rows) ::
              (transp (map List.tl rows))
val transp : 'a list list -> 'a list list = <fun>]]></html:pre>
                    <html:p>A matrix can be viewed as a list of rows, each row a list of matrix elements.
This representation is not especially efficient compared with the conventional
one (using arrays).  Lists of lists turn up often, though, and we can see how
to deal with them by taking familiar matrix operations as examples.
<html:em>ML for the Working Programmer</html:em> goes as far as Gaussian elimination,
which presents surprisingly few difficulties.</html:p>
                    <html:p>The transpose of the matrix
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix} a & b & c \\
                           d & e & f\end {smallmatrix}\right )]]></fr:tex>
is
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix}
        a & d     \\
        b & e     \\
        c & f
   \end {smallmatrix}\right )]]></fr:tex>,
which in OCaml corresponds to the following transformation on lists of lists:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {[[a; b; c]; [d; e; f]]} \Rightarrow & \text { [[a; d]; [b; e]; [c; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>The workings of function <html:code>transp</html:code> are simple.  If <html:code>rows</html:code> is the
matrix to be transposed, then <html:code>map hd</html:code> extracts its first column and
<html:code>map tl</html:code> extracts its second column:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {map hd rows} \Rightarrow  & \text { [a; d]}\\
\text {map tl rows} \Rightarrow  & \text { [[b; c]; [e; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>A recursive call transposes the latter matrix, which is then given the column
<html:code>[a; d]</html:code> as its first row.
The two functions expressed using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> would otherwise have to be declared
separately.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-functionals/</fr:uri>
                    <fr:display-uri>focs-seq-functionals</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-functionals/</fr:route>
                    <fr:title text="Functionals for Lazy Lists">Functionals for Lazy Lists</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Filtering <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec filterq p = function
  | Nil -> Nil
  | Cons (x, xf) ->
      if p x then
        Cons (x, fun () -> filterq p (xf ()))
      else
        filterq p (xf ())
val filterq : ('a -> bool) -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>The infinite sequence <fr:tex display="inline"><![CDATA[x]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(x)]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(f(x))]]></fr:tex>, …</html:p>
                    <html:pre><![CDATA[# let rec iterates f x =
    Cons (x, fun () -> iterates f (f x))
val iterates : ('a -> 'a) -> 'a -> 'a seq = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>filterq</html:code> demands elements of <html:code>xq</html:code> until it finds
one satisfying <html:code>p</html:code>.  (Recall <fr:link href="/~avsm2/fcs/focs-predicate-functionals/" title="List Functionals for Predicates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/" display-uri="focs-predicate-functionals" type="local"><html:code>filter</html:code></fr:link>, the analogous operation for ordinary lists.)  It
contains a <html:em>force</html:em> not protected by a <html:em>delay</html:em>.  If <html:code>xq</html:code> is
infinite and contains no satisfactory element, then <html:code>filtering</html:code> runs
forever.</html:p>
                    <html:p>The functional <html:code>iterates</html:code> generalises <fr:link href="/~avsm2/fcs/focs-infinite-sequence/" title="The Infinite Sequence: k, k+1, k+2, …" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/" display-uri="focs-infinite-sequence" type="local"><html:code>from</html:code></fr:link>.  It creates the
next element not by adding one but by calling the function <html:code>f</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/</fr:uri>
                    <fr:display-uri>focs-anonymous-functions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-anonymous-functions/</fr:route>
                    <fr:title text="Functions Without Names">Functions Without Names</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>If functions are to be regarded as computational values, then we need a
notation for them.  The <html:code>fun</html:code> notation expresses a non-recursive function
value without giving the function a name.</html:p>
                    <html:p><fr:tex display="inline"><![CDATA[\tt  fun\;x\;\rightarrow  E]]></fr:tex> is the function <fr:tex display="inline"><![CDATA[f]]></fr:tex> such that <fr:tex display="inline"><![CDATA[f(x)=E]]></fr:tex>.
The function <html:code>fun n -&gt; n*2</html:code> is a <html:em>doubling function</html:em>.</html:p>
                    <html:pre><![CDATA[# fun n -> n * 2
- : int -> int = <fun>
# (fun n -> n * 2) 17
- : int = 34]]></html:pre>
                    <html:p>The main purpose of <html:code>fun</html:code>-notation is to package up small expressions that are to be
applied repeatedly using some other function.
The expression <html:code>fun n -&gt; n*2</html:code> has the same value as the identifier
<html:code>double</html:code>, declared as follows:</html:p>
                    <html:pre><![CDATA[# let double n = n * 2
val double : int -> int = <fun>]]></html:pre>
                    <html:p>The <html:code>fun</html:code> notation can also do <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matching</fr:link>, and the <html:code>function</html:code> keyword
adds an anonymous variable name to pattern match against.  The following functions
are all equivalent, with the latter definitions bound to the <html:code>is_zero</html:code> value and the earlier ones anonymous:</html:p>
                    <html:pre><![CDATA[# fun x -> match x with 0 -> true | _ -> false
- : int -> bool = <fun>
# function 0 -> true | _ -> false
- : int -> bool = <fun>
# let is_zero = fun x -> match x with 0 -> true | _ -> false
val is_zero : int -> bool = <fun>
# let is_zero = function 0 -> true | _ -> false
val is_zero : int -> bool = <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/</fr:uri>
                    <fr:display-uri>focs-def-higher-order-function</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-higher-order-function/</fr:route>
                    <fr:title text="Higher-order function">Higher-order function</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>In mathematics, a <html:em>functional</html:em> or <html:em>higher-order function</html:em> is a function
that operates on other functions. In OCaml, functions can be passed as arguments
to other functions, returned as results, and put into lists, trees and so on—but
<html:em>not</html:em> tested for equality.
Introduced in <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">Functions as Values</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/</fr:uri>
                    <fr:display-uri>focs-predicate-functionals</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-functionals/</fr:route>
                    <fr:title text="List Functionals for Predicates">List Functionals for Predicates</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec exists p = function
  | [] -> false
  | x::xs -> (p x) || (exists p xs)
val exists : ('a -> bool) -> 'a list -> bool = <fun>
# let rec filter p = function
  | [] -> []
  | x::xs ->
      if p x then
        x :: filter p xs
      else
        filter p xs
val filter : ('a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>A <html:em>predicate</html:em> is a <html:em>boolean-valued</html:em> function.</html:p>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>exists</html:code> transforms a predicate into a predicate over
lists.  Given a list, <html:code>exists p</html:code> tests whether or not some list element
satisfies <html:code>p</html:code> (making it return <html:code>true</html:code>).  If it finds one, it stops
searching immediately, thanks to the behaviour of the lazy <html:code>||</html:code> operator.</html:p>
                    <html:p>Dually, we have a functional to test whether all list elements satisfy the
predicate.  If it finds a counterexample then it, too, stops searching.</html:p>
                    <html:pre><![CDATA[# let rec all p = function
  | [] -> true
  | x::xs -> (p x) && all p xs
val all : ('a -> bool) -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The <html:code>filter</html:code> functional, like <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>, transforms lists.  It applies a
predicate to all the list elements, but instead of returning the
resulting values (which could only be <html:code>true</html:code> or <html:code>false</html:code>), it returns
the list of elements satisfying the predicate.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matmul-ocaml/</fr:uri>
                    <fr:display-uri>focs-matmul-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-matmul-ocaml/</fr:route>
                    <fr:title text="Matrix Multiplication in OCaml">Matrix Multiplication in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:em>Dot product</html:em> of two vectors—a <html:em><fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link></html:em></html:p>
                    <html:pre><![CDATA[# let rec dotprod xs ys =
    match xs, ys with
    | [], [] -> 0.0
    | x::xs, y::ys ->  (x *. y) +. (dotprod xs ys)
Lines 2-4, characters 5-51:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
([], _::_)
val dotprod : float list -> float list -> float = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Matrix product</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let rec matprod arows brows =
    let cols = transp brows in
    map (fun row -> map (dotprod row) cols) arows
val matprod : float list list -> float list list -> float list list = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local"><html:code>transp brows</html:code></fr:link> converts <fr:tex display="inline"><![CDATA[B]]></fr:tex> into a list of columns, yielding a
list whose elements are the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Each row of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is
obtained by multiplying a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex> by the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
                    <html:p>Because <html:code>dotprod</html:code> is curried, it can be applied to a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The
resulting function is applied to all the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  We have another
example of currying and partial application.</html:p>
                    <html:p>The outer <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> applies <html:code>dotprod</html:code> to each row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The inner
<html:code>map</html:code>, using <html:code>fun</html:code>-notation, applies <html:code>dotprod row</html:code> to each
column of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Compare with the version in <html:em>ML for the Working
  Programmer</html:em> (page 89) which does not use <html:code>map</html:code> and requires two
additional function declarations.</html:p>
                    <html:p>In the dot product function, the two vectors must have the same length.
Otherwise, <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Match_failure</html:code> is raised.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-numerical/</fr:uri>
                    <fr:display-uri>focs-seq-numerical</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-numerical/</fr:route>
                    <fr:title text="Numerical Computations on Infinite Sequences">Numerical Computations on Infinite Sequences</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let next a x = (a /. x +. x) /. 2.0
val next : float -> float -> float = <fun>]]></html:pre>
                    <html:p>Close enough?</html:p>
                    <html:pre><![CDATA[# let rec within eps = function
  | Cons (x, xf) ->
      match xf () with
      | Cons (y, yf) ->
          if abs_float (x -. y) <= eps then y
          else within eps (Cons (y, yf))
Lines 3-6, characters 7-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
Lines 1-6, characters 22-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val within : float -> float seq -> float = <fun>]]></html:pre>
                    <html:p>Square Roots:</html:p>
                    <html:pre><![CDATA[# let root a = within 1e-6 (iterates (next a) 1.0)
val root : float -> float = <fun>]]></html:pre>
                    <html:p>The <html:em>Newton-Raphson method</html:em> is widely used for computing square roots.
The infinite series <fr:tex display="inline"><![CDATA[x_0, (a/x_0+x_0)/2, \ldots {}]]></fr:tex> converges rapidly to <fr:tex display="inline"><![CDATA[\sqrt {a}]]></fr:tex>.
The initial approximation, <fr:tex display="inline"><![CDATA[x_0]]></fr:tex>, is typically retrieved from a table, and is accurate enough
that only a few iterations of the method are necessary.
Calling <html:code>iterates (next a) x0</html:code> generates the <html:em>infinite series</html:em> of
approximations to the square root of <fr:tex display="inline"><![CDATA[a]]></fr:tex> using the Newton-Raphson method.
To compute <fr:tex display="inline"><![CDATA[\sqrt 2]]></fr:tex>, the resulting series begins 1, 1.5, 1.41667, 1.4142157, 1.414213562, …,
and this last figure is already accurate to 10 significant digits!</html:p>
                    <html:p>Function <html:code>within</html:code> searches down the <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy list</fr:link> for two points whose
difference is less than <html:code>eps</html:code>.  It tests their absolute difference.
Relative difference and other “close enough” tests can be coded.  Such
components can be used to implement other numerical functions directly as
functions over sequences.  The point is to build programs from small,
interchangeable parts.</html:p>
                    <html:p>Function <html:code>root</html:code> uses <html:code>within</html:code>, <html:code>iterates</html:code> and <html:code>next</html:code> to
to apply Newton-Raphson with a tolerance of <fr:tex display="inline"><![CDATA[10^{-6}]]></fr:tex>
and a (poor) initial approximation of 1.0.</html:p>
                    <html:pre><![CDATA[# root 2.0;;
- : float = 1.41421356237309492]]></html:pre>
                    <html:p>This treatment of numerical computation has received some attention in the
research literature; a recurring example is Richardson extrapolation.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/</fr:uri>
                    <fr:display-uri>focs-partial-application</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-partial-application/</fr:route>
                    <fr:title text="Partial Application: A Curried Insertion Sort">Partial Application: A Curried Insertion Sort</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let insort lessequal =
    let rec ins x = function
      | [] -> [x]
      | y::ys -> if lessequal x y then x :: y :: ys
                 else y :: ins x ys
    in
    let rec sort = function
      | [] -> []
      | x::xs -> ins x (sort xs)
    in
    sort
val insort : ('a -> 'a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-sorting/" title="Sorting" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sorting/" display-uri="focs-sorting" type="local">sorting functions</fr:link> we discussed in earlier lectures are coded to sort floating-point
numbers.  They can be generalised to an arbitrary ordered type by passing the
ordering predicate <html:code>lessequal</html:code> as an argument.</html:p>
                    <html:p>Functions <html:code>ins</html:code> and <html:code>sort</html:code> are declared locally, referring to <html:code>lessequal</html:code>.
Though it may not be obvious, <html:code>insort</html:code> is a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link>.  Given its first
argument, a predicate for comparing some particular type of items, it returns
the function <html:code>sort</html:code> for sorting lists of that type of items.</html:p>
                    <html:p>Some examples of its use:</html:p>
                    <html:pre><![CDATA[# insort (<=) [5; 3; 9; 8]
- : int list = [3; 5; 8; 9]
# insort (<=) ["bitten"; "on"; "a"; "bee"]
- : string list = ["a"; "bee"; "bitten"; "on"]
# insort (>=) [5; 3; 9; 8]
- : int list = [9; 8; 5; 3]]]></html:pre>
                    <html:p>An obscure point: the syntax <html:code>(&lt;=)</html:code> denotes the comparison operator as a
function, which is then given to <html:code>insort</html:code>.  Passing the relation <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex> for
<html:code>lessequal</html:code> gives a decreasing sort.  This is no coding trick; it is justified
in mathematics, since if <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> is a partial ordering then so is <fr:tex display="inline"><![CDATA[\geq ]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/</fr:uri>
                    <fr:display-uri>focs-private-references</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-private-references/</fr:route>
                    <fr:title text="Private, Persistent References">Private, Persistent References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception TooMuch of int
exception TooMuch of int
# let makeAccount initBalance =
    let balance = ref initBalance in
    let withdraw amt =
       if amt > !balance then
         raise (TooMuch (amt - !balance))
       else begin
         balance := !balance - amt;
         !balance
       end
    in
    withdraw
val makeAccount : int -> int -> int = <fun>]]></html:pre>
                    <html:p>As you may have noticed, OCaml’s programming style looks clumsy compared with
that of languages like C.  OCaml omits the defaults and abbreviations they
provide to shorten programs.  However, OCaml’s explicitness makes it ideal for
teaching the fine points of <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> and arrays.  OCaml’s references are more
flexible than those found in other languages.</html:p>
                    <html:p>The function <html:code>makeAccount</html:code> models a bank.  Calling the function with a
specified initial balance creates a new reference <html:code>balance</html:code><![CDATA[)]]> to
maintain the account balance and returns a function (<html:code>withdraw</html:code>) having
sole access to that reference.  Calling <html:code>withdraw</html:code> reduces the balance
by the specified amount and returns the new balance.  You can pay money in by
withdrawing a negative amount.  The <html:code>if</html:code>-construct prevents the account
from going overdrawn, <fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">raising an exception</fr:link>.</html:p>
                    <html:p>Look at the <fr:tex display="inline"><![CDATA[\tt  (E_1; E_2)]]></fr:tex> construct in the <html:em>else</html:em> part above.
The first expression updates the account balance and returns the trivial
value ().  The second expression, <html:code>!balance</html:code>, returns the current
balance but does not return the reference itself: that would allow
unauthorised updates.</html:p>
                    <html:p>This example is based on one by Dr A C Norman.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-curry-shorthand/</fr:uri>
                    <fr:display-uri>focs-curry-shorthand</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-curry-shorthand/</fr:route>
                    <fr:title text="Shorthand for Curried Functions">Shorthand for Curried Functions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A function-returning function is just a function of two arguments.</html:p>
                    <html:p>This <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link> syntax is nicer than nested <html:code>fun</html:code> binders:</html:p>
                    <html:pre><![CDATA[# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>
# let dub = prefix "Sir "
val dub : string -> string = <fun>]]></html:pre>
                    <html:p>Curried functions allows <html:em>partial application</html:em> (to the first argument).</html:p>
                    <html:p>In OCaml, an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-argument curried function <html:code>f</html:code> can be declared using the syntax:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  let \; f \; x_1 \: \ldots  \: x_{n} \: = \: E]]></fr:tex>
                    <html:p>and applied using the syntax:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  \; E_1 \; \ldots  \; E_n]]></fr:tex>
                    <html:p>If <html:code>f</html:code> is not recursive, then it is equivalent to the function expressed via nesting as follows:</html:p>
                    <fr:tex display="block"><![CDATA[\tt  fun \; x_1 \; \rightarrow  \cdots  \rightarrow  fun \; x_{n} \rightarrow  E ]]></fr:tex>
                    <html:p>We now have two ways of expressing functions of multiple arguments: either by
passing a pair of arguments or by currying.  Currying allows <html:em>partial application</html:em>
which is useful when fixing the first argument yields a function
that is interesting in its own right.  An example from mathematics is the
function <fr:tex display="inline"><![CDATA[x^y]]></fr:tex>, where fixing <fr:tex display="inline"><![CDATA[y=2]]></fr:tex> yields a function in <fr:tex display="inline"><![CDATA[x]]></fr:tex> alone, namely
squaring. Similarly, <fr:tex display="inline"><![CDATA[y=3]]></fr:tex> yields cubing, while <fr:tex display="inline"><![CDATA[y=1]]></fr:tex> yields the identity
function.</html:p>
                    <html:p>Though the function <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> (which returns the head of a list) is not
curried, it may be used with the curried application syntax in some
expressions:</html:p>
                    <html:pre><![CDATA[# List.hd [dub; promote] "Hamilton"
- : string = "Sir Hamilton"]]></html:pre>
                    <html:p>Here <html:code>List.hd</html:code> is applied to a list of functions, and the resulting function
<html:code>dub</html:code> is then applied to the string <html:code>"Hamilton"</html:code>.  The idea of
executing code stored in data structures reaches its full development in
<html:em>object-oriented</html:em> programming, like in Java.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bank-accounts/</fr:uri>
                    <fr:display-uri>focs-bank-accounts</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bank-accounts/</fr:route>
                    <fr:title text="Two Bank Accounts">Two Bank Accounts</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let student = makeAccount 500
val student : int -> int = <fun>
# let director = makeAccount 4000000;
val director : int -> int = <fun>
# student 5        (* coach fare *)
- : int = 495
# director 150000  (* Tesla *)
- : int = 3850000
# student 500      (* oh oh *)
Exception: TooMuch 5.]]></html:pre>
                    <html:p>Each call to <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>makeAccount</html:code></fr:link> returns a copy of <html:code>withdraw</html:code> holding
a <html:em>fresh</html:em> instance of the <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> <html:code>balance</html:code>.  As with a real bank
pass-book, there is no access to the account balance except via the
corresponding <html:code>withdraw</html:code> function.  If that function is discarded, the
reference cell becomes unreachable; the computer will eventually reclaim it,
just as banks close down dormant accounts.</html:p>
                    <html:p>Here we see two people managing their accounts.  For better or worse, neither
can take money from the other.</html:p>
                    <html:p>We could generalise <html:code>makeAccount</html:code> to return several functions that
jointly manage information held in shared references.  The functions might be
packaged using OCaml records, which are not discussed in this course.
Most procedural languages do not properly support the concept of private
references, although <html:em>object-oriented</html:em> languages take them as a basic theme.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/</fr:uri>
                    <fr:display-uri>focs-map</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-map/</fr:route>
                    <fr:title text="map: the “Apply to All” Function">map: the “Apply to All” Function</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec map f = function
    | [] -> []
    | x::xs -> (f x) :: map f xs
val map : ('a -> 'b) -> 'a list -> 'b list = <fun>
# map (fun s -> s ^ "ppy") ["Hi"; "Ho"]
- : string list = ["Hippy"; "Hoppy"]
# map (map double) [[1]; [2; 3]]
- : int list list = [[2]; [4; 6]]]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>map</html:code> applies a function to every element of a list,
returning a list of the function’s results.  “Apply to all” is a fundamental
operation and we shall see several applications of it below.  We
again see the advantages of <html:code>fun</html:code>-notation, <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">currying</fr:link> and
<html:code>map</html:code>.  If we did not have them, the first use of <html:code>map</html:code> in the above code block
would require a preliminary function declaration:</html:p>
                    <html:pre><![CDATA[# let rec sillylist = function
    | [] -> []
    | s::ss -> (s ^ "ppy") :: sillylist ss
val sillylist : string list -> string list = <fun>]]></html:pre>
                    <html:p>An expression containing several applications of functionals—such as our
second example—can abbreviate a long series of declarations.  Sometimes this
coding style is cryptic, but it can be clear as crystal.  Treating functions
as values lets us capture common program structures once and for all.</html:p>
                    <html:p>In the second example, <fr:link href="/~avsm2/fcs/focs-anonymous-functions/" title="Functions Without Names" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/" display-uri="focs-anonymous-functions" type="local"><html:code>double</html:code></fr:link> is the obvious integer doubling function we
defined earlier.  Note that <html:code>map</html:code> is a built-in OCaml function in the
form of <html:code>List.map</html:code>.  OCaml’s standard library includes, among much else, many
list functions.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-4/</fr:uri>
                    <fr:display-uri>focs-ex-8-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-4/</fr:route>
                    <fr:title text="Exercises › A map for options"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › A map for options</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The type <html:code>'a option</html:code>, declared below, can be viewed as a type of lists having at most one element.
(It is typically used as an alternative to <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">exceptions</fr:link>.) Declare an analogue of the function <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>
for type <html:code>'a option</html:code>.</html:p>
                    <html:pre><![CDATA[type 'a option = None | Some of 'a]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-1/</fr:uri>
                    <fr:display-uri>focs-ex-9-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-1/</fr:route>
                    <fr:title text="Exercises › A map for sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › A map for sequences</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an analogue of <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> for sequences.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-2/</fr:uri>
                    <fr:display-uri>focs-ex-8-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-2/</fr:route>
                    <fr:title text="Exercises › Lexicographic orderings"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Lexicographic orderings</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>There are many ways of combining orderings. The <html:code>lexicographic ordering</html:code> uses two keys for
comparisons. It is specified by</html:p>
                    <fr:tex display="block"><![CDATA[(x',y')<(x,y)\iff  x'<x \vee  (x'=x \wedge  y'<y).]]></fr:tex>
                    <html:p>Write an OCaml function to lexicographically combine two orderings, supplied as functions. Explain
how it allows function <fr:link href="/~avsm2/fcs/focs-partial-application/" title="Partial Application: A Curried Insertion Sort" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-partial-application/" display-uri="focs-partial-application" type="local"><html:code>insort</html:code></fr:link> to sort a list of pairs.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-5/</fr:uri>
                    <fr:display-uri>focs-ex-8-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-5/</fr:route>
                    <fr:title text="Exercises › Making change with map"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Making change with map</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Recall the making change function of <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">More on Lists</fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec change till amt =
    match till, amt with
    | _       , 0   -> [ [] ]
    | []      , _   -> []
    | c::till , amt -> if amt < c then change till amt
                      else let rec allc = function
                             | [] -> []
                             | cs :: css -> (c::cs) :: allc css
                           in
                             allc (change (c::till) (amt - c)) @
                                   change till amt
val change : int list -> int -> int list list = <fun>]]></html:pre>
                    <html:p>Function <html:code>allc</html:code> applies the function ‘cons a <html:code>c</html:code>’ to every element of a list. Eliminate it by
declaring a <fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried</fr:link> cons function and applying <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-3/</fr:uri>
                    <fr:display-uri>focs-ex-8-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-3/</fr:route>
                    <fr:title text="Exercises › Mapping over lists of lists"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › Mapping over lists of lists</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Without using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> write a function <html:code>map2</html:code> such that <html:code>map2 f</html:code> is equivalent to <html:code>map (map f)</html:code>. The
obvious solution requires declaring two recursive functions. Try to get away with only one by
exploiting nested <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8-1/</fr:uri>
                    <fr:display-uri>focs-ex-8-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-8-1/</fr:route>
                    <fr:title text="Exercises › The argument-swapping functional"><fr:link href="/~avsm2/fcs/focs-ex-8/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-8/" display-uri="focs-ex-8" type="local">Exercises</fr:link> › The argument-swapping functional</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>What does the following function do, and what are its uses?</html:p>
                    <html:pre><![CDATA[let sw f x y = f y x]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-laziness/</fr:uri>
                <fr:display-uri>focs-topic-laziness</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-laziness/</fr:route>
                <fr:title text="Laziness">Laziness</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-pipeline/</fr:uri>
                    <fr:display-uri>focs-pipeline</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-pipeline/</fr:route>
                    <fr:title text="A Pipeline">A Pipeline</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\fbox {\textit {Producer}} \to  \fbox {\textit {Filter}} \to \cdots \to 
 \fbox {\textit {Filter}} \to  \fbox {\textit {Consumer}}
]]></fr:tex>
                    <html:ul><html:li>Produce sequence of items</html:li>
  <html:li>Filter sequence in stages</html:li>
  <html:li>Consume results as needed</html:li>
  <html:li><html:em><fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">Lazy lists</fr:link></html:em> join the stages together</html:li></html:ul>
                    <html:p>Two types of program can be distinguished.  A sequential program
accepts a problem to solve, processes for a while, and finally terminates
with its result.  A typical example is the huge numerical simulations that are
run on supercomputers.  Most of our OCaml functions also fit this model.</html:p>
                    <html:p>At the other extreme are <html:em>reactive</html:em> programs, whose job is to interact
with the environment.  They communicate constantly during their operation and
run for as long as is necessary.  A typical example is the software that
controls many modern aircraft.  Reactive programs often consist of
<html:em>concurrent processes</html:em> running at the same time and communicating with
one another.</html:p>
                    <html:p>Concurrency is too difficult to consider in this course, but we can model
simple pipelines such as that shown above.  The <html:em>Producer</html:em> represents one
or more sources of data, which it outputs as a stream.  The <html:em>Filter</html:em>
stages convert the input stream to an output stream, perhaps consuming several
input items to yield a single output item.  The <html:em>Consumer</html:em> takes as many
elements as necessary.</html:p>
                    <html:p>The Consumer drives the pipeline: nothing is computed except in response to
its demand for an additional datum.  Execution of the Filter stages is
interleaved as required for the computation to go through.  The programmer
sets up the data dependencies but has no clear idea of what happens when.  We
have the illusion of concurrent computation.</html:p>
                    <html:p>The Unix operating system provides similar ideas through its <html:em>pipes</html:em> that
link processes together.  In OCaml, we can model pipelines using <html:em>lazy lists</html:em>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/</fr:uri>
                    <fr:display-uri>focs-seq-consume</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-consume/</fr:route>
                    <fr:title text="Consuming a Sequence">Consuming a Sequence</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec get n s =
    match n, s with
    | 0, _            -> []
    | n, Nil          -> []
    | n, Cons (x, xf) -> x :: get (n-1) (xf ())
val get : int -> 'a seq -> 'a list = <fun>]]></html:pre>
                    <html:p>The above code gets the first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements as a list.
<html:code>xf ()</html:code> <html:em>forces</html:em> evaluation.</html:p>
                    <html:p>The function <html:code>get</html:code> converts a sequence to a list.  It takes the
first <fr:tex display="inline"><![CDATA[n]]></fr:tex> elements; it takes all of them if <fr:tex display="inline"><![CDATA[n<0]]></fr:tex>, which can terminate only if
the sequence is finite.</html:p>
                    <html:p>In the last line of <html:code>get</html:code>, the expression <html:code>xf()</html:code> calls the tail
function, demanding evaluation of the next element.  This operation is called
<html:em>forcing</html:em> the sequence.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-functionals/</fr:uri>
                    <fr:display-uri>focs-seq-functionals</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-functionals/</fr:route>
                    <fr:title text="Functionals for Lazy Lists">Functionals for Lazy Lists</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Filtering <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>:</html:p>
                    <html:pre><![CDATA[# let rec filterq p = function
  | Nil -> Nil
  | Cons (x, xf) ->
      if p x then
        Cons (x, fun () -> filterq p (xf ()))
      else
        filterq p (xf ())
val filterq : ('a -> bool) -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>The infinite sequence <fr:tex display="inline"><![CDATA[x]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(x)]]></fr:tex>, <fr:tex display="inline"><![CDATA[f(f(x))]]></fr:tex>, …</html:p>
                    <html:pre><![CDATA[# let rec iterates f x =
    Cons (x, fun () -> iterates f (f x))
val iterates : ('a -> 'a) -> 'a -> 'a seq = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>filterq</html:code> demands elements of <html:code>xq</html:code> until it finds
one satisfying <html:code>p</html:code>.  (Recall <fr:link href="/~avsm2/fcs/focs-predicate-functionals/" title="List Functionals for Predicates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/" display-uri="focs-predicate-functionals" type="local"><html:code>filter</html:code></fr:link>, the analogous operation for ordinary lists.)  It
contains a <html:em>force</html:em> not protected by a <html:em>delay</html:em>.  If <html:code>xq</html:code> is
infinite and contains no satisfactory element, then <html:code>filtering</html:code> runs
forever.</html:p>
                    <html:p>The functional <html:code>iterates</html:code> generalises <fr:link href="/~avsm2/fcs/focs-infinite-sequence/" title="The Infinite Sequence: k, k+1, k+2, …" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/" display-uri="focs-infinite-sequence" type="local"><html:code>from</html:code></fr:link>.  It creates the
next element not by adding one but by calling the function <html:code>f</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-append/</fr:uri>
                    <fr:display-uri>focs-seq-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-append/</fr:route>
                    <fr:title text="Joining Two Sequences">Joining Two Sequences</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec appendq xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons(x, fun () -> appendq (xf ()) yq)
val appendq : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>A more fair alternative:</html:p>
                    <html:pre><![CDATA[# let rec interleave xq yq =
    match xq with
    | Nil -> yq
    | Cons (x, xf) -> Cons (x, fun () -> interleave yq (xf ()))
val interleave : 'a seq -> 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p>Most list functions and <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> have analogues on sequences, but strange
things can happen.  Can an infinite list be reversed?</html:p>
                    <html:p>Function <html:code>appendq</html:code> is precisely the same idea as <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>
from the <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">Lists lecture</fr:link>; it concatenates two sequences.  If the first
argument is infinite, then <html:code>appendq</html:code> never gets to its second argument,
which is lost.  Concatenation of infinite sequences is not terribly
interesting.</html:p>
                    <html:p>The function <html:code>interleave</html:code> avoids this problem by exchanging the two
arguments in each recursive call.  It combines the two <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, losing no
elements.  Interleaving is the right way to combine two potentially infinite
information sources into one.</html:p>
                    <html:p>In both function declarations, observe that each <html:code>xf ()</html:code> is enclosed
within a <fr:tex display="inline"><![CDATA[{\tt  fun () \rightarrow  \ldots }]]></fr:tex>.  Each <html:em>force</html:em> is enclosed within a
<html:em>delay</html:em>.  This practice makes the functions lazy.  A force not enclosed
in a delay, as in <fr:link href="/~avsm2/fcs/focs-seq-consume/" title="Consuming a Sequence" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-consume/" display-uri="focs-seq-consume" type="local"><html:code>get</html:code></fr:link> above, runs the risk of evaluating the sequence
in full.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/</fr:uri>
                    <fr:display-uri>focs-lazy-lists</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-lazy-lists/</fr:route>
                    <fr:title text="Lazy Lists (or Streams)">Lazy Lists (or Streams)</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Lists of possibly <html:em>infinite</html:em> length</html:li>
  <html:li>Elements <html:em>computed upon demand</html:em></html:li>
  <html:li><html:em>Avoids waste</html:em> if there are many solutions</html:li>
  <html:li><html:em>Infinite</html:em> values are a useful abstraction</html:li></html:ul>
                    <html:p>In OCaml, we can implement laziness by <html:em>delaying evaluation</html:em> of the tail of
the list.</html:p>
                    <html:p>Lazy lists have practical uses.  Some algorithms, like <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>, can
yield many solutions when only a few are required.  Sometimes the original
problem concerns infinite series: with lazy lists, we can pretend they really
exist!</html:p>
                    <html:p>We are now dealing with <html:em>infinite</html:em> (or at least unbounded) computations.
A potentially infinite source of data is processed one element at a time, upon
demand.  Such programs are harder to understand than terminating ones and have
more ways of going wrong.</html:p>
                    <html:p>Some purely functional languages, such as Haskell, use lazy evaluation
everywhere.  Even the if-then-else construct can be a function, and all lists
are lazy.  In OCaml, we can declare a type of lists such that evaluation of the
tail does not occur until demanded.  <html:em>Delayed</html:em> evaluation is weaker than
<html:em>lazy</html:em> evaluation, but it is good enough for our purposes and often the
best compromise for performance and memory usage.</html:p>
                    <html:p>The traditional word “stream” is reserved in OCaml parlance for
input/output channels.  Let us call lazy lists <html:em>sequences</html:em> instead.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-ocaml/</fr:uri>
                    <fr:display-uri>focs-lazy-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-lazy-ocaml/</fr:route>
                    <fr:title text="Lazy Lists in OCaml">Lazy Lists in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>The empty tuple <html:code>()</html:code> and its <html:em>type</html:em> <html:code>unit</html:code></html:li>
  <html:li>Delayed version of <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:code>fun () -&gt; E</html:code></html:li></html:ul>
                    <html:pre><![CDATA[# type 'a seq =
  | Nil
  | Cons of 'a * (unit -> 'a seq)
type 'a seq = Nil | Cons of 'a * (unit -> 'a seq)
# let head (Cons (x, _)) = x
Line 1, characters 10-27:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val head : 'a seq -> 'a = <fun>
# let tail (Cons (_, xf)) = xf ()
Line 1, characters 10-32:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val tail : 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[\tt  Cons(x, xf)]]></fr:tex> has <html:em>head</html:em> <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <html:em>tail function</html:em> <fr:tex display="inline"><![CDATA[xf]]></fr:tex></html:p>
                    <html:p>The primitive OCaml type <html:code>unit</html:code> has one element, which is
written <html:code>()</html:code>.  This element may be regarded as a 0-tuple, and
<html:code>unit</html:code> as the nullary Cartesian product.  (Think of the connection
between multiplication and the number 1.)</html:p>
                    <html:p>The empty tuple serves as a placeholder in situations where no information is
required.  It may:</html:p>
                    <html:ul><html:li>appear in a data structure.  For example, a <html:code>unit</html:code>-valued <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">dictionary</fr:link> represents a set of keys.</html:li>
  <html:li>be the argument of a function, where its effect is to <html:em>delay evaluation</html:em>.</html:li>
  <html:li>be the argument or result of a procedure. (see the <fr:link href="/~avsm2/fcs/focs-procedural-programming/" title="Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/" display-uri="focs-procedural-programming" type="local">Procedural Programming section</fr:link>)</html:li></html:ul>
                    <html:p>The empty tuple, like all tuples, is a constructor and is allowed in patterns;
for example: <html:code>let f () = ...</html:code></html:p>
                    <html:p>In particular <fr:tex display="inline"><![CDATA[\tt  fun \, () \rightarrow  E]]></fr:tex> is the function that takes an argument of
type <html:code>unit</html:code> and returns the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as its result.  Expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>
is not evaluated until the function is called, even though the only possible
argument is <html:code>()</html:code>.  The function simply delays the evaluation of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/</fr:uri>
                    <fr:display-uri>focs-def-lazy-list</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-lazy-list/</fr:route>
                    <fr:title text="Lazy list">Lazy list</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A lazy list is a list of possibly <html:em>infinite</html:em> length whose elements are
<html:em>computed upon demand</html:em>; in OCaml we implement laziness by <html:em>delaying
evaluation</html:em> of the tail of the list. The traditional word “stream” is reserved in
OCaml parlance for input/output channels, so we call lazy lists <html:em>sequences</html:em>
instead.
Introduced in <fr:link href="/~avsm2/fcs/focs-lazy-lists/" title="Lazy Lists (or Streams)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-lists/" display-uri="focs-lazy-lists" type="local">Lazy Lists</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-numerical/</fr:uri>
                    <fr:display-uri>focs-seq-numerical</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-numerical/</fr:route>
                    <fr:title text="Numerical Computations on Infinite Sequences">Numerical Computations on Infinite Sequences</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let next a x = (a /. x +. x) /. 2.0
val next : float -> float -> float = <fun>]]></html:pre>
                    <html:p>Close enough?</html:p>
                    <html:pre><![CDATA[# let rec within eps = function
  | Cons (x, xf) ->
      match xf () with
      | Cons (y, yf) ->
          if abs_float (x -. y) <= eps then y
          else within eps (Cons (y, yf))
Lines 3-6, characters 7-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
Lines 1-6, characters 22-41:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val within : float -> float seq -> float = <fun>]]></html:pre>
                    <html:p>Square Roots:</html:p>
                    <html:pre><![CDATA[# let root a = within 1e-6 (iterates (next a) 1.0)
val root : float -> float = <fun>]]></html:pre>
                    <html:p>The <html:em>Newton-Raphson method</html:em> is widely used for computing square roots.
The infinite series <fr:tex display="inline"><![CDATA[x_0, (a/x_0+x_0)/2, \ldots {}]]></fr:tex> converges rapidly to <fr:tex display="inline"><![CDATA[\sqrt {a}]]></fr:tex>.
The initial approximation, <fr:tex display="inline"><![CDATA[x_0]]></fr:tex>, is typically retrieved from a table, and is accurate enough
that only a few iterations of the method are necessary.
Calling <html:code>iterates (next a) x0</html:code> generates the <html:em>infinite series</html:em> of
approximations to the square root of <fr:tex display="inline"><![CDATA[a]]></fr:tex> using the Newton-Raphson method.
To compute <fr:tex display="inline"><![CDATA[\sqrt 2]]></fr:tex>, the resulting series begins 1, 1.5, 1.41667, 1.4142157, 1.414213562, …,
and this last figure is already accurate to 10 significant digits!</html:p>
                    <html:p>Function <html:code>within</html:code> searches down the <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy list</fr:link> for two points whose
difference is less than <html:code>eps</html:code>.  It tests their absolute difference.
Relative difference and other “close enough” tests can be coded.  Such
components can be used to implement other numerical functions directly as
functions over sequences.  The point is to build programs from small,
interchangeable parts.</html:p>
                    <html:p>Function <html:code>root</html:code> uses <html:code>within</html:code>, <html:code>iterates</html:code> and <html:code>next</html:code> to
to apply Newton-Raphson with a tolerance of <fr:tex display="inline"><![CDATA[10^{-6}]]></fr:tex>
and a (poor) initial approximation of 1.0.</html:p>
                    <html:pre><![CDATA[# root 2.0;;
- : float = 1.41421356237309492]]></html:pre>
                    <html:p>This treatment of numerical computation has received some attention in the
research literature; a recurring example is Richardson extrapolation.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-seq-evaluation/</fr:uri>
                    <fr:display-uri>focs-seq-evaluation</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-seq-evaluation/</fr:route>
                    <fr:title text="Sample Evaluation">Sample Evaluation</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\tt  get(2,\, from \; 6) \\
\tt  get(2,\, Cons(6, fun \; () \rightarrow  from \; (6+1))) \\
\tt  6 :: get(1,\, from \; (6+1)) \\
\tt  6 :: get(1,\, Cons \; (7,\, fun \; () \rightarrow  from \; (7+1))) \\
\tt  6 :: 7 :: get(0,\, Cons \; (8,\, fun \; () \rightarrow  from \; (8+1))) \\
\tt  6 :: 7 :: [] \\
\tt  [6; 7]
\end {aligned}
]]></fr:tex>
                    <html:p>Here we ask for two elements of the infinite sequence.  In fact, three
elements are computed: 6, 7 and 8.  Our implementation is slightly too eager.
A more complicated <html:code>type</html:code> declaration could avoid this problem.
Another problem is that if one repeatedly examines some particular list
element using forcing, that element is repeatedly evaluated.  In a lazy
programming language, the result of the first evaluation would be stored for
later reference.  To get the same effect in OCaml requires the use of
<fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">references</fr:link>.</html:p>
                    <html:p>We should be grateful that the potentially infinite computation is kept
finite.  The tail of the original sequence even contains the unevaluated
expression 6+1.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-infinite-sequence/</fr:uri>
                    <fr:display-uri>focs-infinite-sequence</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-infinite-sequence/</fr:route>
                    <fr:title text="The Infinite Sequence: k, k+1, k+2, …">The Infinite Sequence: <fr:tex display="inline"><![CDATA[k]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+1]]></fr:tex>, <fr:tex display="inline"><![CDATA[k+2]]></fr:tex>, …</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec from k = Cons (k, fun () -> from (k+1))
val from : int -> int seq = <fun>
# let it = from 1
val it : int seq = Cons (1, <fun>)
# let it = tail it
val it : int seq = Cons (2, <fun>)
# let it = tail it
val it : int seq = Cons (3, <fun>)]]></html:pre>
                    <html:p>Function <html:code>from</html:code> constructs the infinite sequence of integers starting
from <fr:tex display="inline"><![CDATA[k]]></fr:tex>.  Execution terminates because of the <html:code>fun</html:code> enclosing the
recursive call.  OCaml displays the tail of a sequence as <html:code>fun</html:code>, which
stands for some function value.  Each call to <html:code>tail</html:code> generates the next
sequence element.  We could do this forever.</html:p>
                    <html:p>This example is of little practical value because the cost of computing a
sequence element will be dominated by that of creating the dummy function.
<fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">Lazy lists</fr:link> tend to have high overheads.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-1/</fr:uri>
                    <fr:display-uri>focs-ex-9-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-1/</fr:route>
                    <fr:title text="Exercises › A map for sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › A map for sequences</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code an analogue of <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> for sequences.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-5/</fr:uri>
                    <fr:display-uri>focs-ex-9-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-5/</fr:route>
                    <fr:title text="Exercises › All lists of zeroes and ones"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › All lists of zeroes and ones</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code the lazy list whose elements are all ordinary lists of zeroes and ones, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 1]; [1; 0]; [1; 1]; [0; 0; 0]; </html:code>….  (Taken from the exam question
2003 Paper 1 Question 5.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-2/</fr:uri>
                    <fr:display-uri>focs-ex-9-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-2/</fr:route>
                    <fr:title text="Exercises › Concatenating infinite sequences"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Concatenating infinite sequences</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider the list function <html:code>concat</html:code>, which concatenates a list of lists to form a single list. Can
it be generalised to concatenate a sequence of sequences? What can go wrong?</html:p>
                    <html:pre><![CDATA[let rec concat = function
| [] -> []
| l::ls -> l @ concat ls]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-6/</fr:uri>
                    <fr:display-uri>focs-ex-9-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-6/</fr:route>
                    <fr:title text="Exercises › Enumerating palindromes"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Enumerating palindromes</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>(Continuing the previous exercise.)
A <html:em>palindrome</html:em> is a list that equals its own reverse. Code the lazy list whose elements are all
palindromes of 0s and 1s, namely
<html:code>[]; [0]; [1]; [0; 0]; [0; 0; 0]; [0; 1; 0]; [1; 1]; [1; 0; 1]; [1; 1; 1]; [0; 0; 0; 0]; </html:code>, …. You
may take the reversal function <html:code>List.rev</html:code> as given.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-4/</fr:uri>
                    <fr:display-uri>focs-ex-9-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-4/</fr:route>
                    <fr:title text="Exercises › Lazy binary trees"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Lazy binary trees</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>lazy binary tree</html:em> is either empty or is a branch containing a label and two lazy <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>,
possibly to infinite depth. Present an OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> to represent lazy binary trees, along with a
function that accepts a lazy binary tree and produces a lazy list that contains all of the tree’s
labels. (Taken from the exam question 2008 Paper 1 Question 5.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9-3/</fr:uri>
                    <fr:display-uri>focs-ex-9-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-9-3/</fr:route>
                    <fr:title text="Exercises › Making change lazily"><fr:link href="/~avsm2/fcs/focs-ex-9/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-9/" display-uri="focs-ex-9" type="local">Exercises</fr:link> › Making change lazily</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Code a function to <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">make change</fr:link> using <fr:link href="/~avsm2/fcs/focs-def-lazy-list/" title="Lazy list" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-lazy-list/" display-uri="focs-def-lazy-list" type="local">lazy lists</fr:link>, delivering the sequence of <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">all possible ways of
making change</fr:link>. Using sequences allows us to compute solutions one at a time when there exists an
astronomical number. Represent lists of coins using ordinary lists. (<html:em>Hint</html:em>: to  benefit from
laziness you may need to pass around the sequence of alternative solutions as a function of type
<html:code>unit -&gt; (int list) seq</html:code>.)</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-queues/</fr:uri>
                <fr:display-uri>focs-topic-queues</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-queues/</fr:route>
                <fr:title text="Queues">Queues</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-search-methods/</fr:uri>
                    <fr:display-uri>focs-search-methods</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-search-methods/</fr:route>
                    <fr:title text="A Survey of Search Methods">A Survey of Search Methods</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Depth-first: use a <html:em>stack</html:em>  (efficient but incomplete)</html:li>
  <html:li>Breadth-first: use a <html:em>queue</html:em> (uses too much space!)</html:li>
  <html:li>Iterative deepening: use depth-first to get benefits of breadth-first (trades time for space)</html:li>
  <html:li>Best-first: use a <html:em>priority queue</html:em> (heuristic search)</html:li></html:ul>
                    <html:p>The data structure determines the search!</html:p>
                    <html:p>Search procedures can be classified by the data structure used to store
pending subtrees.  Depth-first search stores them on a stack, which is
implicit in functions like <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link>, but can be made explicit.
Breadth-first search stores such nodes in a queue.</html:p>
                    <html:p>An important variation is to store the nodes in a priority queue, which
is an ordered sequence.  The priority queue applies some sort of ranking
function to the nodes, placing higher-ranked nodes before lower-ranked ones.
The ranking function typically estimates the distance from the node to a
solution.  If the estimate is good, the solution is located swiftly.  This
method is called best-first search.</html:p>
                    <html:p>The priority queue can be kept as a sorted list, although this is slow.
<fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary search trees</fr:link> would be much better on average, and fancier data
structures improve matters further.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/</fr:uri>
                    <fr:display-uri>focs-queue-adt</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-queue-adt/</fr:route>
                    <fr:title text="An Abstract Data Type: Queues">An Abstract Data Type: Queues</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><html:code>qempty</html:code> is the <html:em>empty queue</html:em></html:li>
  <html:li><html:code>qnull</html:code> <html:em>tests</html:em> whether a queue is empty</html:li>
  <html:li><html:code>qhd</html:code> <html:em>returns</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>deq</html:code> <html:em>discards</html:em> the element at the <html:em>head</html:em> of a queue</html:li>
  <html:li><html:code>enq</html:code> <html:em>adds</html:em> an element at the <html:em>end</html:em> of a queue</html:li></html:ul>
                    <html:p>Breadth-first search becomes much faster if we replace the lists by
<html:em>queues</html:em>.  A queue represents a sequence, allowing elements to be taken
from the head and added to the tail.  This is a First-In-First-Out (FIFO)
discipline: the item next to be removed is the one that has been in the queue
for the longest time.  Lists can implement queues, but <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local">append</fr:link> is a poor means
of adding elements to the tail.</html:p>
                    <html:p>Our <fr:link href="/~avsm2/fcs/focs-functional-arrays/" title="Functional Arrays as Binary Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-arrays/" display-uri="focs-functional-arrays" type="local">functional arrays</fr:link> are suitable, provided we
augment them with a function to delete the first array element.  (See <html:em>ML
  for the Working Programmer</html:em> page 156.)  Each operation would take <fr:tex display="inline"><![CDATA[O(\log 
n)]]></fr:tex> time for a queue of length <fr:tex display="inline"><![CDATA[n]]></fr:tex>.</html:p>
                    <html:p>We shall describe a representation of queues that is purely functional, based
upon lists, and efficient.  Operations take <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> time when “amortized”:
averaged over the lifetime of a queue.</html:p>
                    <html:p>A conventional programming technique is to represent a queue by an array.  Two
indices point to the front and back of the queue, which may wrap around the
end of the array.  The coding is somewhat tricky.  Worse, the length of the
queue must be given a fixed upper bound.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/</fr:uri>
                    <fr:display-uri>focs-stacks</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-stacks/</fr:route>
                    <fr:title text="Another Abstract Data Type: Stacks">Another Abstract Data Type: Stacks</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><html:code>empty</html:code> is the <html:em>empty stack</html:em></html:li>
  <html:li><html:code>null</html:code> tests whether a stack is empty</html:li>
  <html:li><html:code>top</html:code> returns the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>pop</html:code> discards the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>push</html:code> adds an element at the <html:em>top</html:em> of a stack</html:li></html:ul>
                    <html:p>A <html:em>stack</html:em> is a sequence such that items can be added or removed from the head
only.  A stack obeys a Last-In-First-Out (LIFO) discipline: the item next to be
removed is the one that has been in the queue for the <html:em>shortest</html:em> time.  Lists
can easily implement stacks because both <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> affect the head.  But
unlike lists, stacks are often regarded as an imperative data structure: the
effect of <html:code>push</html:code> or <html:code>pop</html:code> is to change an existing stack, not return a new one.</html:p>
                    <html:p>In conventional programming languages, a stack is often implemented by storing
the elements in an array, using a variable (the “stack pointer”) to count them.
Most language processors keep track of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function calls</fr:link> using an
internal stack.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/</fr:uri>
                    <fr:display-uri>focs-bfs-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-queues/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Queues">Breadth-First Tree Traversal — Using Queues</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec breadth q =
    if qnull q then []
    else
      match qhd q with
      | Lf -> breadth (deq q)
      | Br (v, t, u) -> v :: breadth (enq (enq (deq q) t) u)
val breadth : 'a tree queue -> 'a list = <fun>]]></html:pre>
                    <html:p>This function implements the same algorithm as <fr:link href="/~avsm2/fcs/focs-bfs-append/" title="Breadth-First Tree Traversal — Using Append" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/" display-uri="focs-bfs-append" type="local"><html:code>nbreadth</html:code></fr:link> but uses a different
data structure.  It represents queues using type <fr:link href="/~avsm2/fcs/focs-functional-queues/" title="Efficient Functional Queues: Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/" display-uri="focs-functional-queues" type="local"><html:code>queue</html:code></fr:link> instead of type
<html:code>list</html:code>.</html:p>
                    <html:p>To compare their efficiency, I applied both functions to the full binary tree
of depth 12, which contains 4095 labels.  The function <html:code>nbreadth</html:code> took 30
seconds while <html:code>breadth</html:code> took only 0.15 seconds: faster by a factor of 200.</html:p>
                    <html:p>For larger trees, the speedup would be greater.  Choosing the right data
structure pays handsomely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/</fr:uri>
                    <fr:display-uri>focs-functional-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues/</fr:route>
                    <fr:title text="Efficient Functional Queues: Code">Efficient Functional Queues: Code</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type 'a queue =
  | Q of 'a list * 'a list
type 'a queue = Q of 'a list * 'a list
# let norm = function
  | Q ([], tls) -> Q (List.rev tls, [])
  | q -> q
val norm : 'a queue -> 'a queue = <fun>
# let qnull = function
  | Q ([], []) -> true
  | _ -> false
val qnull : 'a queue -> bool = <fun>
# let enq (Q (hds, tls)) x = norm (Q (hds, x::tls))
val enq : 'a queue -> 'a -> 'a queue = <fun>
# exception Empty
exception Empty
# let deq = function
  | Q (x::hds, tls) -> norm (Q (hds, tls))
  | _ -> raise Empty
val deq : 'a queue -> 'a queue = <fun>
# let qempty = Q ([], [])
val qempty : 'a queue = Q ([], [])
# let qhd = function
  | Q (x::_, _) -> x
  | _ -> raise Empty
val qhd : 'a queue -> 'a = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link> of queues prevents confusion with other pairs of lists.  The empty
queue has both parts empty.</html:p>
                    <html:p>The function <html:code>norm</html:code> puts a queue into normal form, ensuring that the front part
is never empty unless the entire queue is empty.  Functions <html:code>deq</html:code> and <html:code>enq</html:code>
call <html:code>norm</html:code> to normalise their result.</html:p>
                    <html:p>Because queues are in normal form, their head is certain to be in their
front part, so <html:code>qhd</html:code> looks there.</html:p>
                    <html:p>Let us analyse the cost of an execution comprising (in any possible order) <fr:tex display="inline"><![CDATA[n]]></fr:tex>
<html:code>enq</html:code> operations and <fr:tex display="inline"><![CDATA[n]]></fr:tex> <html:code>deq</html:code> operations, starting with an
empty queue.  Each <html:code>enq</html:code> operation will perform one cons, adding an
element to the rear part.  Since the final queue must be empty, each element
of the rear part gets transferred to the front part.  The corresponding
reversals perform one cons per element.  Thus, the total cost of the series of
queue operations is <fr:tex display="inline"><![CDATA[2n]]></fr:tex> cons operations, an average of 2 per operation.  The
amortized time is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.</html:p>
                    <html:p>There is a catch.  The conses need not be distributed evenly; reversing a long
list could take up to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex> of them.  Unpredictable delays make the approach
unsuitable for <html:em>real-time programming</html:em> where deadlines must be met.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues-idea/</fr:uri>
                    <fr:display-uri>focs-functional-queues-idea</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-functional-queues-idea/</fr:route>
                    <fr:title text="Efficient Functional Queues: Idea">Efficient Functional Queues: Idea</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Represent the queue <fr:tex display="inline"><![CDATA[x_1\; x_2\; \ldots \; x_m\; y_n\; \ldots \; y_1]]></fr:tex> by any <html:em>pair of lists</html:em>
    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \; [y_1,y_2,\ldots ,y_n])]]></fr:tex></html:li>
  <html:li>Add new items to the <html:em>rear list</html:em></html:li>
  <html:li>Remove items from <html:em>front list</html:em> and if empty move <html:em>rear</html:em> to <html:em>front</html:em></html:li>
  <html:li><html:em>Amortized</html:em> time per operation is <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p>Queues require efficient access at both ends: at the front, for removal, and
at the back, for insertion.  Ideally, access should take constant time,
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex>.  It may appear that lists cannot provide such access.  If
<html:code>enq(q, x)</html:code> performs <html:code>q@[x]</html:code>, then this operation will be <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  We
could represent queues by reversed lists, implementing <html:code>enq(q, x)</html:code> by
<html:code>x::q</html:code>, but then the <html:code>deq</html:code> and <html:code>qhd</html:code> operations would be
<fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Linear time is intolerable: a series of <fr:tex display="inline"><![CDATA[n]]></fr:tex> queue operations
could then require <fr:tex display="inline"><![CDATA[O(n^2)]]></fr:tex> time.</html:p>
                    <html:p>The solution is to represent a queue by a pair of lists, where</html:p>
                    <fr:tex display="block"><![CDATA[([x_1,x_2,\ldots ,x_m], \, [y_1,y_2,\ldots ,y_n])]]></fr:tex>
                    <html:p>represents the queue <fr:tex display="inline"><![CDATA[x_1 x_2 \ldots  x_m y_n \ldots  y_1]]></fr:tex>.</html:p>
                    <html:p>The front part of the queue is stored in order, and the rear part is stored in
reverse order.  The <html:code>enq</html:code> operation adds elements to the rear part
using cons, since this list is reversed; thus, <html:code>enq</html:code> takes constant
time.  The <html:code>deq</html:code> and <html:code>qhd</html:code> operations look at the front part,
which normally takes constant time, since this list is stored in order.  But
sometimes <html:code>deq</html:code> removes the last element from the front part; when this
happens, it reverses the rear part, which becomes the new front part.</html:p>
                    <html:p><html:em>Amortized</html:em> time refers to the cost per operation averaged over the
lifetime of any complete execution.  Even for the worst possible execution,
the average cost per operation turns out to be constant; see the analysis
below.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-2/</fr:uri>
                    <fr:display-uri>focs-ex-10-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-2/</fr:route>
                    <fr:title text="Exercises › Array-based circular queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Array-based circular queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The traditional way to implement queues uses a fixed-length array. Two indices into the array
indicate the start and end of the queue, which wraps around from the end of the array to the start.
How appropriate is such a data structure for implementing <fr:link href="/~avsm2/fcs/focs-bfs-dfs/" title="Breadth-First v Depth-First Tree Traversal" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/" display-uri="focs-bfs-dfs" type="local">breadth-first search</fr:link>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-3/</fr:uri>
                    <fr:display-uri>focs-ex-10-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-3/</fr:route>
                    <fr:title text="Exercises › Rewriting breadth with let"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Rewriting breadth with let</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a version of the function <fr:link href="/~avsm2/fcs/focs-bfs-queues/" title="Breadth-First Tree Traversal — Using Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/" display-uri="focs-bfs-queues" type="local"><html:code>breadth</html:code></fr:link> using a nested <html:code>let</html:code> construction rather than
<html:code>match</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-1/</fr:uri>
                    <fr:display-uri>focs-ex-10-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-1/</fr:route>
                    <fr:title text="Exercises › Tree-based queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Tree-based queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Suppose that we have an implementation of queues, based on <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>, such that each operation
takes logarithmic time in the worst case. Outline the advantages and drawbacks of such an
implementation compared with one presented above.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-search/</fr:uri>
                <fr:display-uri>focs-topic-search</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-search/</fr:route>
                <fr:title text="Search">Search</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-search-methods/</fr:uri>
                    <fr:display-uri>focs-search-methods</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-search-methods/</fr:route>
                    <fr:title text="A Survey of Search Methods">A Survey of Search Methods</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Depth-first: use a <html:em>stack</html:em>  (efficient but incomplete)</html:li>
  <html:li>Breadth-first: use a <html:em>queue</html:em> (uses too much space!)</html:li>
  <html:li>Iterative deepening: use depth-first to get benefits of breadth-first (trades time for space)</html:li>
  <html:li>Best-first: use a <html:em>priority queue</html:em> (heuristic search)</html:li></html:ul>
                    <html:p>The data structure determines the search!</html:p>
                    <html:p>Search procedures can be classified by the data structure used to store
pending subtrees.  Depth-first search stores them on a stack, which is
implicit in functions like <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local"><html:code>inorder</html:code></fr:link>, but can be made explicit.
Breadth-first search stores such nodes in a queue.</html:p>
                    <html:p>An important variation is to store the nodes in a priority queue, which
is an ordered sequence.  The priority queue applies some sort of ranking
function to the nodes, placing higher-ranked nodes before lower-ranked ones.
The ranking function typically estimates the distance from the node to a
solution.  If the estimate is good, the solution is located swiftly.  This
method is called best-first search.</html:p>
                    <html:p>The priority queue can be kept as a sorted list, although this is slow.
<fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">Binary search trees</fr:link> would be much better on average, and fancier data
structures improve matters further.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-applications/</fr:uri>
                    <fr:display-uri>focs-predicate-applications</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-applications/</fr:route>
                    <fr:title text="Applications of the Predicate Functionals">Applications of the Predicate Functionals</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let member y xs =
    exists (fun x -> x=y) xs
val member : 'a -> 'a list -> bool = <fun>
# let inter xs ys =
    filter (fun x -> member x ys) xs
val inter : 'a list -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Testing whether two lists have no common elements</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let disjoint xs ys =
    all (fun x -> all (fun y -> x<>y) ys) xs
val disjoint : 'a list -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The Lists lecture presented the function <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link>, which tests whether a
specified value can be found as a list element, and <html:code>inter</html:code>, which returns the
“intersection” of two lists: the list of elements they have in common.</html:p>
                    <html:p>But remember: the purpose of list <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functionals</fr:link> is not to replace the
declarations of popular functions, which probably are available already.  It is
to eliminate the need for separate declarations of ad-hoc functions.  When they
are nested, like the calls to <html:code>all</html:code> in <html:code>disjoint</html:code> above, the
inner functions are almost certainly one-offs, not worth declaring separately.</html:p>
                    <html:p>Our primitives themselves can be seen as a programming language.  Part of the
task of programming is to extend our programming language with notation for
solving the problem at hand.  The levels of notation that we define should
correspond to natural <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">levels of abstraction</fr:link> in the problem domain.</html:p>
                    <html:p>Historical Note:
Alonzo Church’s <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus gave a simple syntax, <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-notation,
for expressing functions.  It is the direct precursor of OCaml’s
<html:code>fun</html:code>-notation.  It was soon shown that his system was equivalent in
computational power to Turing machines, and <html:em>Church’s thesis</html:em> states that
this defines precisely the set of functions that can be computed effectively.</html:p>
                    <html:p>The <fr:tex display="inline"><![CDATA[\lambda ]]></fr:tex>-calculus had a tremendous influence on the design of functional
programming languages.  McCarthy’s Lisp was something of a false start; it
interpreted variable binding incorrectly, an error that stood for some 20
years.  But in 1966, Peter Landin (of Queen Mary College, University of London)
sketched out the main features of functional languages.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/</fr:uri>
                    <fr:display-uri>focs-bst</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bst/</fr:route>
                    <fr:title text="Binary Search Trees">Binary Search Trees</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>dictionary</html:em> associates <html:em>values</html:em> (here, numbers) with <html:em>keys</html:em>.</html:p>
                    <html:figure>
                      <html:img src="/~avsm2/fcs/bafkrmifkdrvs6ut5buyf724655gdcinx637uevqiaejsmb2jgu36gaf4wq.svg" />
                    </html:figure>
                    <html:p>Binary search trees are an important application of <fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local">binary trees</fr:link>.  They work
for keys that have a total ordering, such as strings.  Each branch of the tree
carries a <fr:tex display="inline"><![CDATA[(key, value)]]></fr:tex> pair; its left subtree holds smaller keys; the right
subtree holds greater keys.  If the tree remains reasonably balanced, then
update and lookup both take <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> for a tree of size <fr:tex display="inline"><![CDATA[n]]></fr:tex>.  These times
hold in the average case; given random data, the tree is likely to remain
balanced.</html:p>
                    <html:p>At a given node, all keys in the left subtree are smaller (or equal) while all
trees in the right subtree are greater.</html:p>
                    <html:p>An unbalanced tree has a linear access time in the worst case.  Examples
include building a tree by repeated insertions of elements in increasing or
decreasing order; there is a close resemblance to <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link>.  Building a binary
search tree, then converting it to <fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">inorder</fr:link>, yields a sorting algorithm called
<html:em>treesort</html:em>.</html:p>
                    <html:p>Self-balancing trees, such as Red-Black trees, attain <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> in the worst
case.  They are complicated to implement.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/</fr:uri>
                    <fr:display-uri>focs-bfs-append</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-append/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Append">Breadth-First Tree Traversal — Using Append</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec nbreadth = function
  | [] -> []
  | Lf :: ts -> nbreadth ts
  | Br (v, t, u) :: ts ->
      v :: nbreadth (ts @ [t; u])
val nbreadth : 'a tree list -> 'a list = <fun>]]></html:pre>
                    <html:p>Keeps an <html:em>enormous queue</html:em> of nodes of search, and is a wasteful use of <fr:link href="/~avsm2/fcs/focs-append/" title="Append: List Concatenation" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-append/" display-uri="focs-append" type="local"><html:code>append</html:code></fr:link>.</html:p>
                    <html:p>Breadth-first search can be inefficient, this naive implementation especially
so.  When the search is at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> of the tree, the list contains all the
remaining trees at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex>, followed by the subtrees (all at depth <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>) of
the trees that have already been visited.  At depth 10, the list could already
contain 1024 elements.  It requires a lot of space, and aggravates this with a
gross misuse of append.  Evaluating <html:code>ts@[t, u]</html:code> copies the long list
<html:code>ts</html:code> just to insert two elements.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-queues/</fr:uri>
                    <fr:display-uri>focs-bfs-queues</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-queues/</fr:route>
                    <fr:title text="Breadth-First Tree Traversal — Using Queues">Breadth-First Tree Traversal — Using Queues</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec breadth q =
    if qnull q then []
    else
      match qhd q with
      | Lf -> breadth (deq q)
      | Br (v, t, u) -> v :: breadth (enq (enq (deq q) t) u)
val breadth : 'a tree queue -> 'a list = <fun>]]></html:pre>
                    <html:p>This function implements the same algorithm as <fr:link href="/~avsm2/fcs/focs-bfs-append/" title="Breadth-First Tree Traversal — Using Append" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-append/" display-uri="focs-bfs-append" type="local"><html:code>nbreadth</html:code></fr:link> but uses a different
data structure.  It represents queues using type <fr:link href="/~avsm2/fcs/focs-functional-queues/" title="Efficient Functional Queues: Code" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functional-queues/" display-uri="focs-functional-queues" type="local"><html:code>queue</html:code></fr:link> instead of type
<html:code>list</html:code>.</html:p>
                    <html:p>To compare their efficiency, I applied both functions to the full binary tree
of depth 12, which contains 4095 labels.  The function <html:code>nbreadth</html:code> took 30
seconds while <html:code>breadth</html:code> took only 0.15 seconds: faster by a factor of 200.</html:p>
                    <html:p>For larger trees, the speedup would be greater.  Choosing the right data
structure pays handsomely.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/</fr:uri>
                    <fr:display-uri>focs-bfs-dfs</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bfs-dfs/</fr:route>
                    <fr:title text="Breadth-First v Depth-First Tree Traversal">Breadth-First v Depth-First Tree Traversal</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>binary trees as <html:em>decision trees</html:em></html:li>
  <html:li>look for <html:em>solution nodes</html:em>
    <html:ul><html:li>Depth-first: search one subtree in full before moving on</html:li>
      <html:li>Breadth-first: search all nodes at level <fr:tex display="inline"><![CDATA[k]]></fr:tex> before moving to <fr:tex display="inline"><![CDATA[k+1]]></fr:tex></html:li></html:ul></html:li>
  <html:li>finds <html:em>all</html:em> solutions — nearest first!</html:li></html:ul>
                    <html:p><fr:link href="/~avsm2/fcs/focs-tree-traversal/" title="Aside: Traversing Trees (3 Methods)" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-tree-traversal/" display-uri="focs-tree-traversal" type="local">Preorder, inorder and postorder tree traversals</fr:link> all have something in common:
they are depth-first.  At each node, the left subtree is entirely
traversed before the right subtree.  Depth-first traversals are easy to code
and can be efficient, but they are ill-suited for some problems.</html:p>
                    <html:p>Suppose the tree represents the possible moves in a puzzle, and the purpose
of the traversal is to search for a node containing a solution.  Then a
depth-first traversal may find one solution node deep in the left subtree,
when another solution is at the very top of the right subtree.  Often we
want the shortest path to a solution.</html:p>
                    <html:p>Suppose the tree is <html:em>infinite</html:em> or simply extremely large.  Depth-first search
is almost useless with such trees, for if the left subtree is infinite then the
search will never reach the right subtree.  OCaml can represent infinite trees by
the means discussed in the <fr:link href="/~avsm2/fcs/focs-sequences/" title="Sequences, or Lazy Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-sequences/" display-uri="focs-sequences" type="local">lecture on laziness</fr:link>. Another tree representation (suitable
for solving solitaire, for example) is by a function <html:code>next : pos -&gt; pos list</html:code>,
which maps a board position to a list of the positions possible after
the next move.  For simplicity, the examples below use the OCaml <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>
<fr:link href="/~avsm2/fcs/focs-binary-trees/" title="Binary Trees, a Recursive Datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-binary-trees/" display-uri="focs-binary-trees" type="local"><html:code>tree</html:code></fr:link>, which has only finite trees.</html:p>
                    <html:p>A <html:em>breadth-first</html:em> traversal explores the nodes horizontally rather than
vertically.  When visiting a node, it does not traverse the subtrees until
it has visited all other nodes at the current depth.  This is easily
implemented by keeping a list of trees to visit.  Initially, this list
consists of one element: the entire tree.  Each iteration removes a tree
from the head of the list and adds its subtrees after the end of the
list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/</fr:uri>
                    <fr:display-uri>focs-equality</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-equality/</fr:route>
                    <fr:title text="Equality Tests">Equality Tests</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec member x = function
   | [] -> false
   | y::l ->
      if x = y then true
      else member x l
val member : 'a -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>All the list functions we have encountered up to now have been “<fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>”,
working for lists of any type.  Function <html:code>member</html:code> uses <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link> to report
whether or not <html:code>x</html:code> occurs in <html:code>l</html:code>.</html:p>
                    <html:p>To do this generically, it uses a special feature of OCaml known as
“polymorphic equality”, which manifests itself via the <html:code>=</html:code>, <html:code>&gt;=</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code> and
<html:code>&lt;</html:code> operators.  These operators inspect the <html:em>structure</html:em> of the values using a
consistent order.  Types you can legitimately compare this way include integers,
strings, booleans, and tuples or lists of primitive types.</html:p>
                    <html:p>More complex types can be compared this way within careful limits: recursive
structures or function values will not work (we will cover function values in
the <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Currying lecture</fr:link> later).  For now, it is sufficient to use these magic
polymorphic equality operators.  As you get more familiar with OCaml and the
use of <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">higher order functions</fr:link> (also covered in a later lecture), you will
encounter the use of explicit <html:code>compare</html:code> functions that are used to provide more
complex equality tests.</html:p>
                    <html:p>The presence of polymorphic equality is a contentious feature in OCaml.  While
it provides a great ease of use in smaller codebases, it starts to become more
dangerous when building larger OCaml-based systems.  Most large-scale users of
OCaml tend towards not using it in important code, but it is just fine for our
purposes while learning the beginning steps of computer science.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/</fr:uri>
                    <fr:display-uri>focs-iterative-deepening</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-iterative-deepening/</fr:route>
                    <fr:title text="Iterative deepening: Another Exhaustive Search">Iterative deepening: Another Exhaustive Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Breadth-first search examines <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> nodes:
    <fr:tex display="block"><![CDATA[1 + b + \cdots  + b^d = {b^{d+1}-1 \over  b-1}
  \qquad  \begin {array}[c]{rl}
            b & {} = \hbox {branching factor}\\
            d & {} = \hbox {depth}
          \end {array}]]></fr:tex></html:li>
  <html:li>Recompute nodes at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> instead of storing them</html:li>
  <html:li>Time factor is <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>; complexity is still <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex></html:li>
  <html:li>Space required at depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> drops from <fr:tex display="inline"><![CDATA[b^d]]></fr:tex> to <fr:tex display="inline"><![CDATA[d]]></fr:tex></html:li></html:ul>
                    <html:p>Breadth-first search is not practical for infinite trees: it uses too much
space. Large parts of the tree have to be stored.
Consider the slightly more general problem of searching trees whose
branching factor is <fr:tex display="inline"><![CDATA[b]]></fr:tex> (for binary trees, <fr:tex display="inline"><![CDATA[b=2]]></fr:tex>).  Then breadth-first search
to depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> examines <fr:tex display="inline"><![CDATA[(b^{d+1}-1)/(b-1)]]></fr:tex> nodes, which is <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>, ignoring
the constant factor of <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex>.  Since all nodes that are examined are also
stored, the space and time requirements are both <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.</html:p>
                    <html:p><html:em>Depth-first iterative deepening</html:em> combines the space efficiency of
depth-first with the “nearest-first” property of breadth-first search.  It
performs repeated depth-first searches with increasing depth bounds, each time
discarding the result of the previous search.  Thus it searches to depth 1,
then to depth 2, and so on until it finds a solution.  We can afford to
discard previous results because the number of nodes is growing exponentially.
There are <fr:tex display="inline"><![CDATA[b^{d+1}]]></fr:tex> nodes at level <fr:tex display="inline"><![CDATA[d+1]]></fr:tex>; if <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex>, this number actually
exceeds the total number of nodes of all previous levels put together, namely
<fr:tex display="inline"><![CDATA[(b^{d+1}-1) / (b-1)]]></fr:tex>.</html:p>
                    <html:p><fr:link href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288" type="external">Korf shows</fr:link> that the time needed for iterative deepening to reach
depth <fr:tex display="inline"><![CDATA[d]]></fr:tex> is only <fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> times that for breadth-first search, if <fr:tex display="inline"><![CDATA[b>1]]></fr:tex>.
This is a constant factor; both algorithms have the same time complexity,
<fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex>.  In typical applications where <fr:tex display="inline"><![CDATA[b\geq 2]]></fr:tex> the extra factor of
<fr:tex display="inline"><![CDATA[b/(b-1)]]></fr:tex> is quite tolerable.  The reduction in the space requirement is
exponential, from <fr:tex display="inline"><![CDATA[O(b^d)]]></fr:tex> for breadth-first to <fr:tex display="inline"><![CDATA[O(d)]]></fr:tex> for iterative
deepening. Of course, this assumes that the tree itself is not stored in memory.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/</fr:uri>
                    <fr:display-uri>focs-linear-search</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-linear-search/</fr:route>
                    <fr:title text="Linear Search">Linear Search</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>find <fr:tex display="inline"><![CDATA[x]]></fr:tex> in list <fr:tex display="inline"><![CDATA[[x_1,\ldots ,x_n]]]></fr:tex> by comparing with each element</html:li>
  <html:li>obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex> time</html:li>
  <html:li>simple &amp; general</html:li>
  <html:li>ordered searching needs only <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex></html:li>
  <html:li>indexed lookup needs only <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex></html:li></html:ul>
                    <html:p><html:em>Linear search</html:em> is the obvious way to find a desired item in a
collection: simply look through all the items, one at a time.  If <fr:tex display="inline"><![CDATA[x]]></fr:tex> is in
the list, then it will be found in <fr:tex display="inline"><![CDATA[n/2]]></fr:tex> steps on average, and even the worst
case is obviously <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                    <html:p>Large collections of data are usually ordered or indexed so that items can be
found in <fr:tex display="inline"><![CDATA[O(\log  n)]]></fr:tex> time, which is exponentially better than <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.  Even
<fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> is achievable (using a hash table), though subject to the usual
proviso that machine limits are not exceeded.</html:p>
                    <html:p>Efficient indexing methods are of prime importance: consider Web
search engines.  Nevertheless, linear search is often used to search small
collections because it is so simple and general, and it is the starting point
for better algorithms.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-predicate-functionals/</fr:uri>
                    <fr:display-uri>focs-predicate-functionals</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-predicate-functionals/</fr:route>
                    <fr:title text="List Functionals for Predicates">List Functionals for Predicates</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec exists p = function
  | [] -> false
  | x::xs -> (p x) || (exists p xs)
val exists : ('a -> bool) -> 'a list -> bool = <fun>
# let rec filter p = function
  | [] -> []
  | x::xs ->
      if p x then
        x :: filter p xs
      else
        filter p xs
val filter : ('a -> bool) -> 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>A <html:em>predicate</html:em> is a <html:em>boolean-valued</html:em> function.</html:p>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-def-higher-order-function/" title="Higher-order function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-higher-order-function/" display-uri="focs-def-higher-order-function" type="local">functional</fr:link> <html:code>exists</html:code> transforms a predicate into a predicate over
lists.  Given a list, <html:code>exists p</html:code> tests whether or not some list element
satisfies <html:code>p</html:code> (making it return <html:code>true</html:code>).  If it finds one, it stops
searching immediately, thanks to the behaviour of the lazy <html:code>||</html:code> operator.</html:p>
                    <html:p>Dually, we have a functional to test whether all list elements satisfy the
predicate.  If it finds a counterexample then it, too, stops searching.</html:p>
                    <html:pre><![CDATA[# let rec all p = function
  | [] -> true
  | x::xs -> (p x) && all p xs
val all : ('a -> bool) -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>The <html:code>filter</html:code> functional, like <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link>, transforms lists.  It applies a
predicate to all the list elements, but instead of returning the
resulting values (which could only be <html:code>true</html:code> or <html:code>false</html:code>), it returns
the list of elements satisfying the predicate.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-exceptions/</fr:uri>
                    <fr:display-uri>focs-change-exceptions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-change-exceptions/</fr:route>
                    <fr:title text="Making Change with Exceptions">Making Change with Exceptions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception Change
  let rec change till amt =
    match till, amt with
    | _, 0         -> []
    | [], _        -> raise Change
    | c::till, amt -> if amt < 0 then raise Change
                      else try c :: change (c::till) (amt - c)
                           with Change -> change till amt
exception Change
val change : int list -> int -> int list = <fun>]]></html:pre>
                    <html:p>In the <fr:link href="/~avsm2/fcs/focs-more-lists/" title="More on Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-more-lists/" display-uri="focs-more-lists" type="local">Lists lectures</fr:link>, we considered the problem of <fr:link href="/~avsm2/fcs/focs-making-change/" title="An Application: Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-making-change/" display-uri="focs-making-change" type="local">making change</fr:link>.  The greedy
algorithm presented there could not express “6 using 5 and 2” because it always
took the largest coin.  Returning <fr:link href="/~avsm2/fcs/focs-change-all/" title="All Ways of Making Change" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-change-all/" display-uri="focs-change-all" type="local">the list of all possible solutions</fr:link> avoids
that problem rather expensively: we only need one solution.</html:p>
                    <html:p>Using <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exceptions</fr:link>, we can code a <html:em>backtracking</html:em> algorithm: one that can undo
past decisions if it comes to a dead end.  The exception <html:code>Change</html:code> is raised if
we run out of coins (with a non-zero amount) or if the amount goes negative.
We always try the largest coin, but enclose the recursive call in an exception
handler, which undoes the choice if it goes wrong.</html:p>
                    <html:p>Carefully observe how exceptions interact with <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.  The exception
handler always undoes the <html:em>most recent</html:em> choice, leaving others possibly to
be undone later.  If making change really is impossible, then eventually
<html:code>exception Change</html:code> will be raised with no handler to catch it, and it
will be reported at top level.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-5/</fr:uri>
                    <fr:display-uri>focs-ex-10-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-5/</fr:route>
                    <fr:title text="Exercises › An implicit infinite tree"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › An implicit infinite tree</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider the following OCaml function.</html:p>
                    <html:pre><![CDATA[let next n = [2 * n; 2 * n + 1]]]></html:pre>
                    <html:p>If we regard it as representing a tree, where the subtrees are computed from the current label, what
tree does <html:code>next 1</html:code> represent?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-2/</fr:uri>
                    <fr:display-uri>focs-ex-10-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-2/</fr:route>
                    <fr:title text="Exercises › Array-based circular queues"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Array-based circular queues</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>The traditional way to implement queues uses a fixed-length array. Two indices into the array
indicate the start and end of the queue, which wraps around from the end of the array to the start.
How appropriate is such a data structure for implementing <fr:link href="/~avsm2/fcs/focs-bfs-dfs/" title="Breadth-First v Depth-First Tree Traversal" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bfs-dfs/" display-uri="focs-bfs-dfs" type="local">breadth-first search</fr:link>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10-4/</fr:uri>
                    <fr:display-uri>focs-ex-10-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-10-4/</fr:route>
                    <fr:title text="Exercises › Search with a branching factor near one"><fr:link href="/~avsm2/fcs/focs-ex-10/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-10/" display-uri="focs-ex-10" type="local">Exercises</fr:link> › Search with a branching factor near one</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><fr:link href="/~avsm2/fcs/focs-iterative-deepening/" title="Iterative deepening: Another Exhaustive Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-iterative-deepening/" display-uri="focs-iterative-deepening" type="local">Iterative deepening</fr:link> is inappropriate if <fr:tex display="inline"><![CDATA[b\approx 1]]></fr:tex>, where <fr:tex display="inline"><![CDATA[b]]></fr:tex> is the branching factor. What search
strategy is appropriate in this case?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-1/</fr:uri>
                    <fr:display-uri>focs-ex-4-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-1/</fr:route>
                    <fr:title text="Exercises › Set union without repetitions"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Set union without repetitions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Sets can be represented in OCaml using lists containing no duplicated items
(i.e. where no item is equal to another using <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link> comparison).</html:p>
                    <html:p>Using the <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local"><html:code>member</html:code></fr:link> function defined above, code a function to implement set
union. It should avoid introducing repetitions, for example the union of the
lists <html:code>[4; 7; 1]</html:code> and <html:code>[6; 4; 7]</html:code> should be <html:code>[1; 6; 4; 7]</html:code> (though the order
does not matter).</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-imperative/</fr:uri>
                <fr:display-uri>focs-topic-imperative</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-imperative/</fr:route>
                <fr:title text="Imperative">Imperative</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-stacks/</fr:uri>
                    <fr:display-uri>focs-stacks</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-stacks/</fr:route>
                    <fr:title text="Another Abstract Data Type: Stacks">Another Abstract Data Type: Stacks</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><html:code>empty</html:code> is the <html:em>empty stack</html:em></html:li>
  <html:li><html:code>null</html:code> tests whether a stack is empty</html:li>
  <html:li><html:code>top</html:code> returns the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>pop</html:code> discards the element at the <html:em>top</html:em> of a stack</html:li>
  <html:li><html:code>push</html:code> adds an element at the <html:em>top</html:em> of a stack</html:li></html:ul>
                    <html:p>A <html:em>stack</html:em> is a sequence such that items can be added or removed from the head
only.  A stack obeys a Last-In-First-Out (LIFO) discipline: the item next to be
removed is the one that has been in the queue for the <html:em>shortest</html:em> time.  Lists
can easily implement stacks because both <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local"><html:code>cons</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local"><html:code>hd</html:code></fr:link> affect the head.  But
unlike lists, stacks are often regarded as an imperative data structure: the
effect of <html:code>push</html:code> or <html:code>pop</html:code> is to change an existing stack, not return a new one.</html:p>
                    <html:p>In conventional programming languages, a stack is often implemented by storing
the elements in an array, using a variable (the “stack pointer”) to count them.
Most language processors keep track of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursive function calls</fr:link> using an
internal stack.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-examples/</fr:uri>
                    <fr:display-uri>focs-array-examples</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-array-examples/</fr:route>
                    <fr:title text="Array Examples">Array Examples</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>In the following session, the identifier <html:code>ar</html:code> is bound to an array of 20 elements, which
are initially set to the squares of their subscripts.  The array’s third
element (which actually has subscript 2) is inspected and found to be four. The
second call to <html:code>Array.get</html:code> supplies a subscript that is out of range, so OCaml
rejects it.</html:p>
                    <html:pre><![CDATA[# let ar = Array.init 20 (fun i -> i * i)
val ar : int array =
  [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
    289; 324; 361|]
# Array.get ar 2
- : int = 4
# Array.get ar 20
Exception: Invalid_argument "index out of bounds".
# Array.set ar 2 33; ar
- : int array =
[|0; 1; 33; 9; 16; 25; 36; 49; 64; 81; 100; 121; 144; 169; 196; 225; 256;
  289; 324; 361|]]]></html:pre>
                    <html:p>By calling <html:code>Array.set</html:code>, we then modify the element with subscript 2. Note
however that we cannot modify the array’s length. If we outgrow the array, we
have to create a new one, copy the data into it, and then forget the old array.
Typically the new array would be double the size of the old one, so that the
cost of copying is insignificant.</html:p>
                    <html:p>OCaml provides numerous operators for modifying, computing over and searching in
arrays. Many are analogous to <fr:link href="/~avsm2/fcs/focs-lists/" title="Lists" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lists/" display-uri="focs-lists" type="local">functions on lists</fr:link>. For example,
<html:code>Array.exists</html:code> takes a boolean-valued function and returns <html:code>true</html:code> if an
array element satisfies it.</html:p>
                    <html:pre><![CDATA[# Array.exists (fun i -> i > 200) ar
- : bool = true
# Array.exists (fun i -> i < 0) ar
- : bool = false]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-arrays/</fr:uri>
                    <fr:display-uri>focs-arrays</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-arrays/</fr:route>
                    <fr:title text="Arrays">Arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>A conventional array is an indexed storage area.
  <html:ul><html:li>It is updated <html:em>in place</html:em> by the command <html:code>a.(k) &lt;- x</html:code></html:li>
  <html:li>The concept is inherently <html:em>imperative</html:em>.</html:li></html:ul></html:li>
<html:li>A <html:em>functional array</html:em> is a finite map from integers to data.
  <html:ul><html:li>Updating implies <html:em>copying</html:em> to return <html:code>update(A, k, x)</html:code></html:li>
  <html:li>The new array equals <html:code>A</html:code> except that <html:code>A.(k) = x</html:code>.</html:li></html:ul></html:li>
<html:li>Can we do updates efficiently?</html:li></html:ul>
                    <html:p>The elements of a list can only be reached by counting from the front.
Elements of a tree are reached by following a path from the root.  An
<html:em>array</html:em> hides such structural matters; its elements are uniformly
designated by number.  Immediate access to arbitrary parts of a data structure
is called <html:em>random access</html:em>.</html:p>
                    <html:p>Arrays are the dominant data structure in conventional programming languages.
The ingenious use of arrays is the key to many of the great classical
algorithms, such as Hoare’s original <fr:link href="/~avsm2/fcs/focs-quicksort-idea/" title="Quicksort: The Idea" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-quicksort-idea/" display-uri="focs-quicksort-idea" type="local">quicksort</fr:link> (the partition step) and
Warshall’s transitive-closure algorithm.</html:p>
                    <html:p>The drawback is that subscripting is a chief cause of programmer error.  That
is why arrays play little role in this introductory course.</html:p>
                    <html:p>Functional arrays are described below in order to illustrate another way of
using trees to organise data.  Here is a summary of basic dictionary data
structures in order of decreasing generality and increasing efficiency:</html:p>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">Linear search</fr:link>: Most general, needing only equality on keys, but inefficient: linear time.</html:li>
<html:li>Binary search: Needs an ordering on keys.  Logarithmic access time in the average case, but our <fr:link href="/~avsm2/fcs/focs-bst/" title="Binary Search Trees" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bst/" display-uri="focs-bst" type="local">binary search trees</fr:link> are linear in the worst case.</html:li>
<html:li>Array subscripting: Least general, requiring keys to be integers, but even worst-case time is logarithmic.</html:li></html:ul>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-commands/</fr:uri>
                    <fr:display-uri>focs-commands</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-commands/</fr:route>
                    <fr:title text="Commands: Expressions with Effects">Commands: Expressions with Effects</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Basic commands update <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link>, write to files, etc.</html:li>
  <html:li><fr:tex display="inline"><![CDATA[C_1 ; \ldots  ; C_n]]></fr:tex> causes a series of expressions to be evaluated and returns the value of <fr:tex display="inline"><![CDATA[C_n]]></fr:tex>.</html:li>
  <html:li>A typical command returns the empty tuple: <html:code>()</html:code></html:li>
  <html:li><html:code>if</html:code> <fr:tex display="inline"><![CDATA[B]]></fr:tex> <html:code>then</html:code> <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> <html:code>else</html:code> <fr:tex display="inline"><![CDATA[C_2]]></fr:tex> behaves like the traditional control structure if <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> and <fr:tex display="inline"><![CDATA[C_2]]></fr:tex> have effects.</html:li>
  <html:li>Other OCaml constructs behave naturally with commands, including <html:code>match</html:code> expressions and recursive functions.</html:li></html:ul>
                    <html:p>We use the term <html:em>command</html:em> informally to refer to an expression that has an
effect on the state. All expressions denote some value, but they can return
<html:code>()</html:code>, which conveys no actual information.</html:p>
                    <html:p>We need a way to execute one command after another.
The construct <fr:tex display="inline"><![CDATA[C_1 ; \ldots  ; C_n]]></fr:tex> evaluates the expressions <fr:tex display="inline"><![CDATA[C_1]]></fr:tex>
to <fr:tex display="inline"><![CDATA[C_n]]></fr:tex> in the order given and returns the value of <fr:tex display="inline"><![CDATA[C_n]]></fr:tex>.  The values
of the other expressions are discarded; their only purpose is to change the
state.</html:p>
                    <html:p>Commands may be used with <html:code>if</html:code> and <html:code>match</html:code> much as in conventional languages.
OCaml functions play the role of procedures.</html:p>
                    <html:p>Other languages that combine the functional and imperative programming
paradigms include Lisp (and its dialect Scheme), Scala, and even a
systems programming language, BLISS (now long extinct).</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-goals-of-programming/</fr:uri>
                    <fr:display-uri>focs-goals-of-programming</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-goals-of-programming/</fr:route>
                    <fr:title text="Goals of Programming">Goals of Programming</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>to describe a computation so that it can be done <html:strong>mechanically</html:strong>:
    <html:ul><html:li>Expressions compute values.</html:li>
      <html:li>Commands cause effects.</html:li></html:ul></html:li>
  <html:li>to do so efficiently and <html:strong>correctly</html:strong>, giving the right answers quickly</html:li>
  <html:li>to allow easy modification as needs change
    <html:ul><html:li>Through an orderly <html:strong>structure</html:strong> based on <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstraction principles</fr:link></html:li>
      <html:li>Such as modules or classes</html:li></html:ul></html:li></html:ul>
                    <html:p>Programming <html:em>in-the-small</html:em> concerns the writing of code to do simple, clearly
defined tasks. Programs provide expressions for describing mathematical
formulae and so forth. This was the original contribution of FORTRAN, the
FORmula TRANslator. Commands describe how control should flow from one part of
the program to the next.</html:p>
                    <html:p>As we code layer upon layer, we eventually find ourselves programming
<html:em>in the large</html:em> : joining large modules to solve some messy task. Programming
languages have used various mechanisms to allow one part of the program to
provide interfaces to other parts. Modules encapsulate a body of code, allowing
outside access only through a programmer-defined interface. <fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local"><html:em>Abstract Data
Types</html:em></fr:link> are a simpler version of this concept, which implement a single concept
such as dates or floating-point numbers.</html:p>
                    <html:p><html:em>Object-oriented programming</html:em> is the most complicated approach to modularity.
<html:em>Classes</html:em> define concepts, and they can be built upon other classes. Operations
can be defined that work in appropriately specialised ways on a family of
related classes. <html:em>Objects</html:em> are instances of classes and hold the data that is
being manipulated.</html:p>
                    <html:p>This course does not cover OCaml’s sophisticated module system, which can do
many of the same things as classes. You will learn all about objects when you
study Java. OCaml includes a powerful object system, although this is not used
as much as its module system.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/</fr:uri>
                    <fr:display-uri>focs-while</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-while/</fr:route>
                    <fr:title text="Iteration: the while command">Iteration: the while command</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let tlopt = function
  | [] -> None
  | _::xs -> Some xs
val tlopt : 'a list -> 'a list option = <fun>
# let length xs =
    let lp  = ref xs in (* list of uncounted elements *)
    let np  = ref 0  in (* accumulated count *)
    let fin = ref false in
    while not !fin do
      match tlopt !lp with
      | None -> fin := true
      | Some xs ->
          lp := xs;
          np := 1 + !np
    done;
    !np (* the final count is returned *)
val length : 'a list -> int = <fun>]]></html:pre>
                    <html:p>Once we can change the state, we need to do so repeatedly.  <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">Recursion</fr:link> can
serve this purpose, but having to declare a procedure for every loop is
clumsy, and compilers for conventional languages seldom exploit
<fr:link href="/~avsm2/fcs/focs-recursion-vs-iteration/" title="Recursion vs Iteration" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/" display-uri="focs-recursion-vs-iteration" type="local">tail-recursion</fr:link>.</html:p>
                    <html:p>Early programming languages provided little support for repetition.  The
programmer had to set up loops using goto commands, exiting the loop using
another goto controlled by an <html:code>if</html:code>.  Modern languages provide a
confusing jumble of looping constructs, the most fundamental of which is
<html:code>while B do C</html:code>.  The boolean expression <fr:tex display="inline"><![CDATA[B]]></fr:tex> is evaluated,
and if true, command <fr:tex display="inline"><![CDATA[C]]></fr:tex> is executed and the command repeats.  If <fr:tex display="inline"><![CDATA[B]]></fr:tex>
evaluates to false then the <html:code>while</html:code> command terminates, perhaps without
executing <fr:tex display="inline"><![CDATA[C]]></fr:tex> even once.</html:p>
                    <html:p>OCaml’s main looping construct is <html:code>while</html:code>, which returns the value <html:code>()</html:code>.  The
function <html:code>length</html:code> declares <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> to hold the list under
examination (<html:code>lp</html:code>) and number of elements counted so far (<html:code>np</html:code>) as well
as whether the end of the list has been reached (the boolean reference <html:code>fin</html:code>).
While the list is non-empty, we skip over one more element (by setting it to
its tail) and count that element.</html:p>
                    <html:p>The body of the <html:code>while</html:code> loop first checks to see if the end of the list has
been reached, in which case it sets the <html:code>fin</html:code> variable to true.  If there is a
tail value, then two assignments are executed in sequence.  The <html:code>lp</html:code> reference
is set to the tail of the list, and the <html:code>np</html:code> reference integer is incremented
by one.  When the while loop terminates due to the <html:code>fin</html:code> variable being set to
true, the expression <html:code>!np</html:code> returns the computed length as the function’s
result.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/</fr:uri>
                    <fr:display-uri>focs-def-mutable-reference</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-mutable-reference/</fr:route>
                    <fr:title text="Mutable reference">Mutable reference</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A reference is a cell in the store, also called a “location”: <html:code>ref E</html:code>
creates a reference with initial contents the value of <html:code>E</html:code>, <html:code>!P</html:code>
returns the current contents of reference <html:code>P</html:code> (an operation called
<html:em>dereferencing</html:em>), and <html:code>P := E</html:code> updates the contents of <html:code>P</html:code> to the
value of <html:code>E</html:code>. If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the
type of references to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">OCaml Primitives for References</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/</fr:uri>
                    <fr:display-uri>focs-array-primitives</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-array-primitives/</fr:route>
                    <fr:title text="OCaml Primitives for Arrays">OCaml Primitives for Arrays</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# [|"a"; "b"; "c"|] (* allocate a fresh string array *)
- : string array = [|"a"; "b"; "c"|]
# Array.make 3 'a'   (* array[3] with cell containing 'a' *)
- : char array = [|'a'; 'a'; 'a'|]
# let aa = Array.init 5 (fun i -> i * 10) (* array[5] initialised to (fun i) *)
val aa : int array = [|0; 10; 20; 30; 40|]
# Array.get aa 3  (* retrieve the 4th cell in the array *)
- : int = 30
# Array.set aa 3 42 (* set the 4th cell's value to 42 *)
- : unit = ()]]></html:pre>
                    <html:p>There are many other array operations in the <html:code>Array</html:code> module in the OCaml standard
library.</html:p>
                    <html:pre><![CDATA[# Array.make
- : int -> 'a -> 'a array = <fun>
# Array.init
- : int -> (int -> 'a) -> 'a array = <fun>
# Array.get
- : 'a array -> int -> 'a = <fun>
# Array.set
- : 'a array -> int -> 'a -> unit = <fun>]]></html:pre>
                    <html:p>OCaml arrays are like <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> that hold several elements instead of one.  The
elements of an <fr:tex display="inline"><![CDATA[n]]></fr:tex>-element array are designated by the integers from 0
to <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.  The <fr:tex display="inline"><![CDATA[i]]></fr:tex>th array element is usually written <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.
If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is a type then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>array</html:code> is the
type of arrays (of any size) with elements from <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.</html:p>
                    <html:p>Calling <html:code>Array.init n f</html:code> creates an array of the size specified in <fr:tex display="inline"><![CDATA[n]]></fr:tex>
by function <fr:tex display="inline"><![CDATA[f]]></fr:tex>.  Initially, element <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex> holds the value of <fr:tex display="inline"><![CDATA[f(i)]]></fr:tex> for <fr:tex display="inline"><![CDATA[i=0]]></fr:tex>, …, <fr:tex display="inline"><![CDATA[n-1]]></fr:tex>.
Like <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local"><html:code>ref</html:code></fr:link>, it allocates mutable storage to hold the specified values.</html:p>
                    <html:p>Calling <html:code>Array.get A i</html:code> returns the contents of <fr:tex display="inline"><![CDATA[A.(i)]]></fr:tex>.</html:p>
                    <html:p>Calling <html:code>Array.set A i E</html:code> modifies the array <fr:tex display="inline"><![CDATA[A]]></fr:tex> by storing the
value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as the new contents of <fr:tex display="inline"><![CDATA[A[i]]]></fr:tex>; it returns <html:code>()</html:code> as its value.</html:p>
                    <html:p>OCaml’s arrays are much safer than C’s. In C, an array is nothing more than an
address indicating the start of a storage area. Nothing indicates the size of
the area.  Therefore C programs are vulnerable to <html:em>buffer overrun attacks:</html:em> an
attacker sends more data than the receiving program expects, overrunning the
area of storage set aside to hold it. The attack eventually overwrites the
program itself, replacing it with code controlled by the attacker.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/</fr:uri>
                    <fr:display-uri>focs-references</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references/</fr:route>
                    <fr:title text="OCaml Primitives for References">OCaml Primitives for References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>Effect</html:th></html:tr>
  <html:tr><html:td><html:code>ref E</html:code></html:td><html:td><html:em>create</html:em> a reference with <html:em>initial contents</html:em> = value of <html:code>E</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!P</html:code></html:td><html:td>return <html:em>current contents</html:em> of reference <html:code>P</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>P := E</html:code></html:td><html:td><html:em>update</html:em> contents of <html:code>P</html:code> to value of <html:code>E</html:code></html:td></html:tr>
</html:table>
                    <html:p>The above text presents the OCaml primitives, but most languages have analogues of
them, often heavily disguised.  We need a means of creating references (or
allocating storage), getting at the current contents of a reference cell, and
updating that cell.</html:p>
                    <html:p>The function <html:code>ref</html:code> creates references (also called
“locations”).  Calling <html:code>ref</html:code> allocates a new location in memory.
Initially, this location holds the value given by
expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
                    <html:p>The function <html:code>!</html:code>, when applied to a reference, returns its contents.
This operation is called <html:em>dereferencing</html:em>.  Clearly <html:code>!</html:code> is not a
mathematical function; its result depends upon the store.</html:p>
                    <html:p>The assignment <html:code>P:=E</html:code> evaluates expression <fr:tex display="inline"><![CDATA[P]]></fr:tex>, which must return a
reference <fr:tex display="inline"><![CDATA[p]]></fr:tex>, and <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It stores at address <fr:tex display="inline"><![CDATA[p]]></fr:tex> the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.
Syntactically, <html:code>:=</html:code> is a function and <html:code>P:=E</html:code> is an
expression, even though it updates the store.  Like many functions that change
the state, it returns the value <html:code>()</html:code> of type <html:code>unit</html:code>.</html:p>
                    <html:p>If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the type of references
to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.  Please do not confuse the type
<html:code>ref</html:code> with the function <html:code>ref</html:code>.  This table of the primitive
functions and their types might be useful:</html:p>
                    <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>OCaml Type</html:th></html:tr>
  <html:tr><html:td><html:code>ref</html:code></html:td><html:td><html:code>'a -&gt; 'a ref</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!</html:code></html:td><html:td><html:code>'a ref -&gt; 'a</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>:=</html:code></html:td><html:td><html:code>'a ref -&gt; 'a -&gt; unit</html:code></html:td></html:tr>
</html:table>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/</fr:uri>
                    <fr:display-uri>focs-private-references</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-private-references/</fr:route>
                    <fr:title text="Private, Persistent References">Private, Persistent References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# exception TooMuch of int
exception TooMuch of int
# let makeAccount initBalance =
    let balance = ref initBalance in
    let withdraw amt =
       if amt > !balance then
         raise (TooMuch (amt - !balance))
       else begin
         balance := !balance - amt;
         !balance
       end
    in
    withdraw
val makeAccount : int -> int -> int = <fun>]]></html:pre>
                    <html:p>As you may have noticed, OCaml’s programming style looks clumsy compared with
that of languages like C.  OCaml omits the defaults and abbreviations they
provide to shorten programs.  However, OCaml’s explicitness makes it ideal for
teaching the fine points of <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link> and arrays.  OCaml’s references are more
flexible than those found in other languages.</html:p>
                    <html:p>The function <html:code>makeAccount</html:code> models a bank.  Calling the function with a
specified initial balance creates a new reference <html:code>balance</html:code><![CDATA[)]]> to
maintain the account balance and returns a function (<html:code>withdraw</html:code>) having
sole access to that reference.  Calling <html:code>withdraw</html:code> reduces the balance
by the specified amount and returns the new balance.  You can pay money in by
withdrawing a negative amount.  The <html:code>if</html:code>-construct prevents the account
from going overdrawn, <fr:link href="/~avsm2/fcs/focs-ocaml-exceptions/" title="Exceptions in OCaml" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ocaml-exceptions/" display-uri="focs-ocaml-exceptions" type="local">raising an exception</fr:link>.</html:p>
                    <html:p>Look at the <fr:tex display="inline"><![CDATA[\tt  (E_1; E_2)]]></fr:tex> construct in the <html:em>else</html:em> part above.
The first expression updates the account balance and returns the trivial
value ().  The second expression, <html:code>!balance</html:code>, returns the current
balance but does not return the reference itself: that would allow
unauthorised updates.</html:p>
                    <html:p>This example is based on one by Dr A C Norman.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/</fr:uri>
                    <fr:display-uri>focs-procedural-programming</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-procedural-programming/</fr:route>
                    <fr:title text="Procedural Programming">Procedural Programming</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>Procedural programs can change the machine state.</html:li>
  <html:li>They can interact with its environment</html:li>
  <html:li>They use control structures like branching, iteration and procedures.</html:li></html:ul>
                    <html:p>They use data abstractions of the computer’s memory:</html:p>
                    <html:ul><html:li><html:em><fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link></html:em> to memory cells</html:li>
  <html:li><html:em>arrays</html:em> that are blocks of memory cells</html:li>
  <html:li><html:em>linked structures</html:em> such as <html:em>linked lists</html:em></html:li></html:ul>
                    <html:p>Procedural programming is programming in the traditional sense of the word.  A
program <html:em>state</html:em> is repeatedly transformed by the execution of
<html:em>commands</html:em> or <html:em>statements</html:em>.  A state change might be local to the
machine and consist of updating a variable or array.  A state change might
consist of sending data to the outside world.  Even reading data counts as a
state change, since this act normally removes the data from the environment.</html:p>
                    <html:p>Procedural programming languages provide primitive commands and control
structures for combining them.  The primitive commands include
<html:em>assignment</html:em> for updating variables, and various <html:em>input/output</html:em>
commands for communication.  Control structures include <html:code>if</html:code> and
<html:code>match</html:code> constructs for conditional execution, and repetitive constructs
such as <html:code>while</html:code>.  Programmers can package up their own commands as
<html:em>procedures</html:em> taking arguments.  The need for such “subroutines” was
evident from the earliest days; they represent one of the first
examples of <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstraction</fr:link> in programming languages.</html:p>
                    <html:p>OCaml makes no distinction between commands and expressions. OCaml provides built-in
‘functions’ to perform assignment and communication, and these can be used
in the traditional (procedural) style. OCaml programmers often follow a
functional style for most internal computations and use imperative features
mainly for communication with the outside world.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-recursion-vs-iteration/</fr:uri>
                    <fr:display-uri>focs-recursion-vs-iteration</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-recursion-vs-iteration/</fr:route>
                    <fr:title text="Recursion vs Iteration">Recursion vs Iteration</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>“Iterative” normally refers to a loop, coded using <html:code>while</html:code> for example (see the <fr:link href="/~avsm2/fcs/focs-procedural/" title="Elements of Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural/" display-uri="focs-procedural" type="local">final lecture</fr:link>)</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-tail-recursion/" title="Tail recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-tail-recursion/" display-uri="focs-def-tail-recursion" type="local">Tail-recursion</fr:link> is only efficient if the compiler detects it</html:li>
  <html:li>Mainly it saves space (memory), though iterative code can also run faster</html:li>
  <html:li>Do not make programs iterative unless the gain is worth it</html:li></html:ul>
                    <html:p>A <fr:link href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs" type="external">classic book</fr:link>
by Abelson and Sussman, which describes the Lisp dialect known as Scheme,
used <html:em>iterative</html:em> to mean <html:em>tail-recursive</html:em>. Iterative functions produce computations
resembling those that can be done using while-loops in conventional languages.</html:p>
                    <html:p>Many algorithms can be expressed naturally using <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>, but only awkwardly
using iteration. There is a story that Dijkstra sneaked recursion into Algol-60
by inserting the words “any other occurrence of the procedure name denotes
execution of the procedure.” By not using the word “recursion”, he managed to
slip this amendment past sceptical colleagues.</html:p>
                    <html:p>Obsession with tail recursion leads to a coding style in which functions
have many more arguments than necessary.  Write straightforward code first,
avoiding only gross inefficiency.  If the program turns out to be too slow,
tools are available for pinpointing the cause.  Always remember KISS (Keep
It Simple, Stupid).</html:p>
                    <html:p>I hope you have all noticed by now that the summation can be done even more
efficiently using the arithmetic progression formula:</html:p>
                    <fr:tex display="block"><![CDATA[1+\cdots +n = n(n+1)/2]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-comparison/</fr:uri>
                    <fr:display-uri>focs-references-comparison</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references-comparison/</fr:route>
                    <fr:title text="References: OCaml vs conventional languages">References: OCaml vs conventional languages</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>We must write <html:code>!p</html:code> to get the <html:em>contents</html:em> of <html:code>p</html:code></html:li>
  <html:li>We write just <html:code>p</html:code> for the <html:em>address</html:em> of <html:code>p</html:code></html:li>
  <html:li>We can store private <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference cells</fr:link> (like <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>balance</html:code></fr:link>) in functions—analogous to elements of <html:em>object-oriented programming</html:em></html:li>
  <html:li>OCaml’s assignment syntax is <fr:tex display="inline"><![CDATA[\tt  V \, := \, E]]></fr:tex> instead of <fr:tex display="inline"><![CDATA[V]]></fr:tex> = <fr:tex display="inline"><![CDATA[E]]></fr:tex></html:li>
  <html:li>OCaml has few control structures: <fr:link href="/~avsm2/fcs/focs-while/" title="Iteration: the while command" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-while/" display-uri="focs-while" type="local"><html:code>while</html:code></fr:link>, <html:code>match</html:code>, <html:code>if</html:code> and <html:code>for</html:code> (the latter is not covered in this course)</html:li>
  <html:li>OCaml has syntax for updating an array via the <html:code>a.(i) &lt;- v</html:code> syntax which is the same as <fr:link href="/~avsm2/fcs/focs-array-primitives/" title="OCaml Primitives for Arrays" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-array-primitives/" display-uri="focs-array-primitives" type="local"><html:code>Array.set a i v</html:code></fr:link>.</html:li></html:ul>
                    <html:p>Conventional syntax for variables and assignments has hardly changed since
Fortran, the first high-level language. In conventional languages,
virtually all variables can be updated.  We declare something like
<html:code>p: int</html:code>, mentioning no reference type even if the language provides
them.  If we do not specify an initial value, we may get whatever bits were
previously at that address.  Illegal values arising from uninitialised
variables can cause errors that are almost impossible to diagnose.</html:p>
                    <html:p>Dereferencing operators (like OCaml’s <html:code>!</html:code>) are especially unpopular, because
they clutter the program text. Virtually all programming languages make dereferencing
implicit (that is, automatic).</html:p>
                    <html:p>It is generally accepted these days that a two-dimensional array <fr:tex display="inline"><![CDATA[A]]></fr:tex> is nothing
but an array of arrays.  An assignment to such an array is typically written
something like <fr:tex display="inline"><![CDATA[A[i,j] {:=} x]]></fr:tex>; in C, the syntax is <html:code>A[i][j] = x</html:code>. Higher
dimensions are treated analogously.  The corresponding OCaml code can either
declare an array of arrays, or use the <html:code>A.(i)</html:code> syntax to calculate the linear
offset into a single array.</html:p>
                    <html:p>You can use the constructs we have learnt to easily create linked (mutable) lists as
an alternative to arrays.</html:p>
                    <html:pre><![CDATA[# type 'a mlist =
  | Nil
  | Cons of 'a * 'a mlist ref
type 'a mlist = Nil | Cons of 'a * 'a mlist ref]]></html:pre>
                    <html:p>It is worth mentioning that OCaml’s references fully suffice for coding the sort of linked data structures
taught in algorithms courses, and is illustrated in the figure above. The
programming style is a little different from the usual, but the principles are
the same.  OCaml also provides comprehensive input/output primitives for various
types of file and operating system.</html:p>
                    <html:p>OCaml’s system of modules include <html:em>structures,</html:em> which can be seen as encapsulated
groups of declarations, and <html:em>signatures,</html:em> which are specifications of
structures listing the name and type of each component.  Finally, there are
<html:em>functors,</html:em> which are analogous to functions that combine a number of argument
structures, and which can be used to plug program components together. These
primitives are useful for managing large programming projects.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-examples/</fr:uri>
                    <fr:display-uri>focs-references-examples</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references-examples/</fr:route>
                    <fr:title text="Trying Out References">Trying Out References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let p = ref 5 (* create a reference *)
val p : int ref = {contents = 5}
# p := !p + 1   (* p now holds value 6 *)
- : unit = ()
# let ps = [ ref 77; p ]
val ps : int ref list = [{contents = 77}; {contents = 6}]
# List.hd ps := 3
- : unit = ()
# ps
- : int ref list = [{contents = 3}; {contents = 6}]]]></html:pre>
                    <html:p>The first line declares <html:code>p</html:code> to hold a <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> to an integer,
initially 5.  Its type is <html:code>int ref</html:code>, not just <html:code>int</html:code>, so it
admits assignment.  Assignment never changes <html:code>let</html:code> bindings: they are
<html:em>immutable</html:em>.  The identifier <html:code>p</html:code> will always denote the reference
mentioned in its declaration unless superseded by a new usage of <html:code>p</html:code>.
Only the <html:em>contents</html:em> of the reference is mutable.</html:p>
                    <html:p>OCaml displays a reference value as <html:code><![CDATA[{contents=v}]]></html:code>, where value <fr:tex display="inline"><![CDATA[v]]></fr:tex> is the
contents.  This notation is readable but gives us no way of telling whether
two references holding the same value are actually the same reference.  To
display a reference as a machine address has obvious drawbacks!</html:p>
                    <html:p>In the first assignment, the expression <html:code>!p</html:code> yields the reference’s
current contents, namely 5.  The assignment changes the contents of <html:code>p</html:code>
to 6.  Most languages do not have an explicit dereferencing operator
(like <html:code>!</html:code>) because of its inconvenience.  Instead, by convention,
occurrences of the reference on the <html:em>left-hand</html:em> side of the <html:code>:=</html:code>
denote locations and those on the <html:em>right-hand</html:em> side denote the contents.
A special ‘address of’ operator may be available to override the convention
and make a reference on the right-hand side to denote a location.  Logically
this is a mess, but it makes programs shorter.</html:p>
                    <html:p>The list <html:code>ps</html:code> is declared to hold a new reference (initially
containing 77) as well as <html:code>p</html:code>.  Then the new reference is
updated to hold 3.  The assignment to <html:code>hd ps</html:code> does <html:em>not</html:em>
update <html:code>ps</html:code>, only the contents of a reference in that list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-bank-accounts/</fr:uri>
                    <fr:display-uri>focs-bank-accounts</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-bank-accounts/</fr:route>
                    <fr:title text="Two Bank Accounts">Two Bank Accounts</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let student = makeAccount 500
val student : int -> int = <fun>
# let director = makeAccount 4000000;
val director : int -> int = <fun>
# student 5        (* coach fare *)
- : int = 495
# director 150000  (* Tesla *)
- : int = 3850000
# student 500      (* oh oh *)
Exception: TooMuch 5.]]></html:pre>
                    <html:p>Each call to <fr:link href="/~avsm2/fcs/focs-private-references/" title="Private, Persistent References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-private-references/" display-uri="focs-private-references" type="local"><html:code>makeAccount</html:code></fr:link> returns a copy of <html:code>withdraw</html:code> holding
a <html:em>fresh</html:em> instance of the <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> <html:code>balance</html:code>.  As with a real bank
pass-book, there is no access to the account balance except via the
corresponding <html:code>withdraw</html:code> function.  If that function is discarded, the
reference cell becomes unreachable; the computer will eventually reclaim it,
just as banks close down dormant accounts.</html:p>
                    <html:p>Here we see two people managing their accounts.  For better or worse, neither
can take money from the other.</html:p>
                    <html:p>We could generalise <html:code>makeAccount</html:code> to return several functions that
jointly manage information held in shared references.  The functions might be
packaged using OCaml records, which are not discussed in this course.
Most procedural languages do not properly support the concept of private
references, although <html:em>object-oriented</html:em> languages take them as a basic theme.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-3/</fr:uri>
                    <fr:display-uri>focs-ex-11-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-3/</fr:route>
                    <fr:title text="Exercises › Effects in a while condition"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Effects in a while condition</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>What is the effect of <fr:tex display="inline"><![CDATA[\tt  while \, C_1; \; B \, do \, C_2 \, done]]></fr:tex> ?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-4/</fr:uri>
                    <fr:display-uri>focs-ex-11-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-4/</fr:route>
                    <fr:title text="Exercises › Exchanging two references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Exchanging two references</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a function to exchange the values of two <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">references</fr:link>, <html:code>xr</html:code> and <html:code>yr</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-2/</fr:uri>
                    <fr:display-uri>focs-ex-11-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-2/</fr:route>
                    <fr:title text="Exercises › Iterative power with while"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Iterative power with while</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Write a version of function <html:code>power</html:code> (<fr:link href="/~avsm2/fcs/focs-intro/" title="Introduction to Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" type="local">Lecture <fr:contextual-number uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-intro/" display-uri="focs-intro" /></fr:link>) using <html:code>while</html:code> instead of <fr:link href="/~avsm2/fcs/focs-def-recursion/" title="Recursion" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-recursion/" display-uri="focs-def-recursion" type="local">recursion</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-1/</fr:uri>
                    <fr:display-uri>focs-ex-11-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-1/</fr:route>
                    <fr:title text="Exercises › Lists of references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Lists of references</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Comment, with examples, on the differences between an <html:code>int ref list</html:code> and an <html:code>int list ref</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-types/</fr:uri>
                <fr:display-uri>focs-topic-types</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-types/</fr:route>
                <fr:title text="Types">Types</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/</fr:uri>
                    <fr:display-uri>focs-constructors-args</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-constructors-args/</fr:route>
                    <fr:title text="A Datatype whose Constructors have Arguments">A Datatype whose Constructors have Arguments</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int
               | Car       of bool
               | Lorry     of int
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
                    <html:ul><html:li>Constructors with arguments (like <html:code>Lorry</html:code>) are <html:em>distinct values</html:em>. (So <html:code>Car true</html:code> is distinct from <html:code>Car false</html:code>).</html:li>
  <html:li>Different kinds of <html:code>vehicle</html:code> can belong to one list: <html:code>[Bike, Car true, Motorbike 450]</html:code></html:li></html:ul>
                    <html:p>OCaml generalises the notion of enumeration type to allow data to be associated
with each constructor.  The constructor <html:code>Bike</html:code> is a vehicle all by itself, but
the other three constructors create vehicles from arguments.</html:p>
                    <html:p>Since we might find it hard to remember what the various <html:code>int</html:code> and
<html:code>bool</html:code> components are for, it is wise to include <html:em>comments</html:em> in
complex declarations.  In OCaml, comments are enclosed in the brackets
<html:code><![CDATA[(*]]></html:code> and <html:code><![CDATA[*)]]></html:code>. Programmers should comment their code to explain
design decisions and key features of the algorithms (sometimes by citing a
reference work).</html:p>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike of int  (* engine size in CCs *)
               | Car       of bool (* true if a Reliant Robin *)
               | Lorry     of int  (* number of wheels *)
type vehicle = Bike | Motorbike of int | Car of bool | Lorry of int]]></html:pre>
                    <html:p>The list shown on the slide represents a bicycle, a Reliant Robin and a large
motorbike.  It can be almost seen as a mixed-type list containing integers and
booleans.  It is actually a list of vehicles; datatypes lessen the impact of
the restriction that all list elements must have the same type.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-first-session/</fr:uri>
                    <fr:display-uri>focs-first-session</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-first-session/</fr:route>
                    <fr:title text="A first session with OCaml">A first session with OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let pi = 3.14159265358979
val pi : float = 3.14159265358979]]></html:pre>
                    <html:p>The first line of this simple session is a <html:em>value declaration</html:em>. It makes the
name <html:code>pi</html:code> stand for the floating point number <html:code>3.14159</html:code>. (Such names are called
<html:em>identifiers</html:em>.)  OCaml echoes the name (<html:code>pi</html:code>) and type (<html:code>float</html:code>) of the
declared identifier.</html:p>
                    <html:pre><![CDATA[# pi *. 1.5 *. 1.5
- : float = 7.06858347057702829]]></html:pre>
                    <html:p>The second line computes the area of the circle with radius <html:code>1.5</html:code> using the
formula <fr:tex display="inline"><![CDATA[A = \pi  r^2]]></fr:tex>. We use <html:code>pi</html:code> as an abbreviation for <html:code>3.14159</html:code>.
Multiplication is expressed using <html:code>*.</html:code>, which is called an <html:em>infix operator</html:em>
because it is written between its two operands.</html:p>
                    <html:p>OCaml replies with the computed value (about <html:code>7.07</html:code>) and its type (again <html:code>float</html:code>).</html:p>
                    <html:pre><![CDATA[# let area r = pi *. r *. r
val area : float -> float = <fun>]]></html:pre>
                    <html:p>To work <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstractly</fr:link>, we should provide the service “compute the area of a
circle,” so that we no longer need to remember the formula. This sort of
encapsulated computation is called a <html:em>function</html:em>. The third line declares the
function <html:code>area</html:code>. Given any floating point number <html:code>r</html:code>, it returns another
floating point number computed using the <html:code>area</html:code> formula; note that the function
has type <html:code>float -&gt; float</html:code>.</html:p>
                    <html:pre><![CDATA[# area 2.0
- : float = 12.56637061435916]]></html:pre>
                    <html:p>The fourth line calls the function <html:code>area</html:code> supplying <html:code>2.0</html:code> as the argument. A
circle of radius <html:code>2</html:code> has an area of about <html:code>12.6</html:code>. Note that brackets around a
function argument are not necessary.</html:p>
                    <html:p>The function uses <html:code>pi</html:code> to stand for <html:code>3.14159</html:code>. Unlike what you may have seen in
other programming languages, <html:code>pi</html:code> cannot be "assigned to" or otherwise updated.
Its meaning within <html:code>area</html:code> will persist even if we issue a new <html:code>let</html:code> declaration
for <html:code>pi</html:code> afterwards.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/</fr:uri>
                    <fr:display-uri>focs-def-abstraction-barrier</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-abstraction-barrier/</fr:route>
                    <fr:title text="Abstraction barrier">Abstraction barrier</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Large systems can only be understood in levels: the interface to the higher
level should supply the advertised services and, just as important, block access
to the means by which those services are implemented. This abstraction barrier
allows one level to be changed without affecting levels above.
Introduced in <fr:link href="/~avsm2/fcs/focs-basic-concepts/" title="Basic Concepts in Computer Science" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-basic-concepts/" display-uri="focs-basic-concepts" type="local">Basic Concepts in Computer Science</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/</fr:uri>
                    <fr:display-uri>focs-def-algebraic-datatype</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-algebraic-datatype/</fr:route>
                    <fr:title text="Algebraic datatype">Algebraic datatype</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>OCaml generalises the notion of enumeration type to allow data to be
associated with each constructor: some constructors are values all by themselves,
while others create values from arguments. Constructors with arguments are
<html:em>distinct values</html:em>, and values built from different constructors of one
datatype can belong to a single list.
Introduced in <fr:link href="/~avsm2/fcs/focs-constructors-args/" title="A Datatype whose Constructors have Arguments" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-constructors-args/" display-uri="focs-constructors-args" type="local">A Datatype whose Constructors have Arguments</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-enumeration/</fr:uri>
                    <fr:display-uri>focs-enumeration</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-enumeration/</fr:route>
                    <fr:title text="An Enumeration Type">An Enumeration Type</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We will now learn how to define more expressive types than the
basic ones supplied with the core OCaml language.</html:p>
                    <html:pre><![CDATA[# type vehicle = Bike
               | Motorbike
               | Car
               | Lorry
type vehicle = Bike | Motorbike | Car | Lorry]]></html:pre>
                    <html:ul><html:li>We have declared a <html:em>new type</html:em> named <html:code>vehicle</html:code>.</html:li>
  <html:li><fr:tex display="inline"><![CDATA[\ldots ]]></fr:tex> along with four new constants.</html:li>
  <html:li>They are the <html:em>constructors</html:em> of the <fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">datatype</fr:link>.</html:li></html:ul>
                    <html:p>The <html:code>type</html:code> declaration adds a new type to our OCaml session.  Type
<html:code>vehicle</html:code> is as good as any built-in type and even admits
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> (as we used with the <fr:link href="/~avsm2/fcs/focs-list-primitives/" title="The List Primitives" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-list-primitives/" display-uri="focs-list-primitives" type="local">built-in list types</fr:link> earlier).
The four new identifiers of type <html:code>vehicle</html:code> are called <html:em>constructors</html:em>.</html:p>
                    <html:p>We could represent the various vehicles by the numbers 0–3.  However, the code would be
hard to read and even harder to maintain.  Consider adding <html:code>Tricycle</html:code>
as a new vehicle. If we wanted to add it before <html:code>Bike</html:code>, then all the
numbers would have to be changed.  Using <html:code>type</html:code>, such additions are
trivial and the compiler can (at least sometimes) warn us when it encounters a
function declaration that doesn’t yet have a case for <html:code>Tricycle</html:code>.</html:p>
                    <html:p>Representing vehicles by strings like <html:code>"Bike"</html:code>, <html:code>"Car"</html:code>, etc.,
is also bad.  Comparing string values is slow and the compiler
can’t warn us of misspellings like <html:code>"MOtorbike"</html:code>: they will make our
code fail.</html:p>
                    <html:p>Most programming languages allow the declaration of types like
<html:code>vehicle</html:code>.  Because they consist of a series of identifiers, they are
called <html:em>enumeration types</html:em>.  Other common examples are days of the week
or colours.  The compiler chooses the integers for us; type-checking prevents
us from confusing <html:code>Bike</html:code> with <html:code>Red</html:code> or <html:code>Sunday</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-basic-concepts/</fr:uri>
                    <fr:display-uri>focs-basic-concepts</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-basic-concepts/</fr:route>
                    <fr:title text="Basic Concepts in Computer Science">Basic Concepts in Computer Science</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter><html:ul><html:li>Computers: a child can use them; <html:strong>nobody</html:strong> can fully understand them!</html:li>
  <html:li>We can master complexity through levels of abstraction.</html:li>
  <html:li>Focus on 2 or 3 levels at most!</html:li></html:ul><html:p><html:strong>Recurring issues:</html:strong></html:p><html:ul><html:li><html:em>what services</html:em> to provide at each level</html:li>
  <html:li><html:em>how to implement</html:em> them using lower-level services</html:li>
  <html:li><html:em>the interface</html:em> that defines how the two levels should communicate</html:li></html:ul><html:p>A basic concept in computer science is that large systems can only be
understood in levels, with each level further subdivided into functions or
services of some sort. The interface to the higher level should supply the
advertised services. Just as important, it should block access to the means by
which those services are implemented. This <html:em>abstraction barrier</html:em> allows one
level to be changed without affecting levels above. For example, when a
manufacturer designs a faster version of a processor, it is essential that
existing programs continue to run on it. Any differences between the old and
new processors should be invisible to the program.</html:p><html:p>Modern processors have elaborate specifications, which still sometimes leave
out important details. In the old days, you then had to consult the circuit
diagrams.</html:p>

<fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link></fr:author></fr:authors><fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/</fr:uri><fr:display-uri>focs-dates</fr:display-uri><fr:route>/~avsm2/fcs/focs-dates/</fr:route><fr:title text="Example 1: Dates">Example 1: Dates</fr:title></fr:frontmatter><fr:mainmatter><html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">Abstract level</fr:link>: dates over a certain interval</html:li>
  <html:li>Concrete level: could be 6 characters: <html:code>YYMMDD</html:code> (where each character is represented by 8 bits)</html:li>
  <html:li>Date crises caused by <html:strong>inadequate</html:strong> internal formats:
    <html:ul><html:li>Digital’s PDP-10: using 12-bit dates (good for at most 11 years)</html:li>
      <html:li>2000 crisis: 48 bits could be good for lifetime of universe!</html:li></html:ul></html:li></html:ul><html:p>Digital Equipment Corporation’s date crisis occurred in 1975.  The
PDP-10 was a 36-bit mainframe computer. It represented dates using a 12-bit
format designed for the tiny PDP-8. With 12 bits, one can distinguish
<fr:tex display="inline"><![CDATA[2^{12} = 4096]]></fr:tex> days or 11 years.</html:p><html:p>Last century, the most common industry format for dates used six characters: two for the
year, two for the month and two for the day. The most common “solution” to the
year 2000 crisis is to add two further characters, thereby altering file sizes.
Others have noticed that the existing six characters consist of 48 bits,
already sufficient to represent all dates over the projected lifetime of the
universe: <fr:tex display="inline"><![CDATA[2^{48}]]></fr:tex> = <fr:tex display="inline"><![CDATA[2.8\times  10^{14}]]></fr:tex> days = <fr:tex display="inline"><![CDATA[7.7\times  10^{11}]]></fr:tex> years!</html:p><html:p>Mathematicians think in terms of unbounded ranges, but the representation we
choose for the computer usually imposes hard limits. A good programming
language like OCaml lets one easily change the representation used in the
program.  But if files in the old representation exist all over the place,
there will still be conversion problems. The need for compatibility with older
systems causes problems across the computer industry.</html:p></fr:mainmatter></fr:tree>
<fr:tree show-metadata="false" numbered="false"><fr:frontmatter><fr:authors><fr:author><fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link></fr:author></fr:authors><fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/</fr:uri><fr:display-uri>focs-floating-point</fr:display-uri><fr:route>/~avsm2/fcs/focs-floating-point/</fr:route><fr:title text="Example 2: Floating Point Numbers">Example 2: Floating Point Numbers</fr:title></fr:frontmatter><fr:mainmatter><html:p>Computers have integers like <html:code>1066</html:code> and floats like <fr:tex display="inline"><![CDATA[1.066\times  10^3]]></fr:tex>.
A floating-point number is represented by two integers.
The concept of <html:em>data type</html:em> involves:</html:p><html:ul><html:li>how a value is represented inside the computer</html:li>
  <html:li>the suite of operations given to programmers</html:li>
  <html:li>valid and invalid (or exceptional) results, such as “infinity”</html:li></html:ul><html:p>Computer arithmetic can yield <html:em>incorrect answers!</html:em></html:p><html:p>In science, numbers written with finite precision and a decimal exponent are
said to be in <html:em>standard form</html:em>. The computational equivalent is the <html:em>floating
point number</html:em>. These are familiar to anybody who has used a scientific
calculator.  Internally, a float consists of two integers.</html:p><html:p>Because of its finite precision, floating-point computations are potentially
inaccurate. To see an example, use your nearest electronic calculator to
compute <fr:tex display="inline"><![CDATA[(2^{1/10000})^{10000}]]></fr:tex>. I get <fr:tex display="inline"><![CDATA[1.99999959]]></fr:tex>! With certain computations,
the errors spiral out of control. Many programming languages fail to check
whether even integer computations fall within the allowed range: you can add
two positive integers and get a negative one!</html:p><html:p>Most computers give us a choice of precisions. In 32-bit precision, integers
typically range from <fr:tex display="inline"><![CDATA[2^{31}-1]]></fr:tex> (namely 2 147 483 647) to <fr:tex display="inline"><![CDATA[-2^{31}]]></fr:tex>; floats
are accurate to about six decimal places and can get as large as <fr:tex display="inline"><![CDATA[10^{35}]]></fr:tex> or so.
For floats, 64-bit precision is often preferred. Early languages like Fortran
required variables to be declared as <html:code>INTEGER</html:code>, <html:code>REAL</html:code> or <html:code>COMPLEX</html:code> and barred
programmers from mixing numbers in a computation. Nowadays, programs handle
many different kinds of data, including text and symbols. The concept of a
<html:em>data type</html:em> can ensure that different types of data are not combined in a
senseless way.</html:p><html:p>Inside the computer, all data are stored as bits. In most programming
languages, the compiler uses types to generate correct machine code, and types
are not stored during program execution. In this course, we focus almost
entirely on programming in a high-level language: OCaml.</html:p></fr:mainmatter></fr:tree>
</fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-vehicles/</fr:uri>
                    <fr:display-uri>focs-vehicles</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-vehicles/</fr:route>
                    <fr:title text="Declaring a Function on Vehicles">Declaring a Function on Vehicles</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let wheels = function
  | Bike -> 2
  | Motorbike -> 2
  | Car -> 4
  | Lorry -> 18
val wheels : vehicle -> int = <fun>]]></html:pre>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-algebraic-datatype/" title="Algebraic datatype" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-algebraic-datatype/" display-uri="focs-def-algebraic-datatype" type="local">Datatype constructors</fr:link> can be used in patterns.</html:li>
  <html:li><fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">Pattern-matching</fr:link> is fast, even complicated nested patterns.</html:li>
  <html:li>Notice the type of the argument is <html:code>vehicle</html:code>, which we defined earlier.</html:li></html:ul>
                    <html:p>The beauty of datatype declarations is that the new types behave as if they
were built into OCaml. Type-checking catches common errors, such as mixing up
different datatypes in a function like <html:code>wheels</html:code>, as well as missing
and redundant patterns.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/</fr:uri>
                    <fr:display-uri>focs-dictionary-adt</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-dictionary-adt/</fr:route>
                    <fr:title text="Dictionaries">Dictionaries</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>lookup: find an item in the dictionary</html:li>
<html:li>update (insert): replace (store) an item in the dictionary</html:li>
<html:li>delete: remove an item from the dictionary</html:li>
<html:li>empty: the null dictionary</html:li>
<html:li>Missing: <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> for errors in <html:code>lookup</html:code> and <html:code>delete</html:code></html:li></html:ul>
                    <html:p>Ideally, an <html:em>abstract type</html:em> should provide these operations and hide the internal data structures.</html:p>
                    <html:p>A dictionary attaches values to identifiers, called “keys”.  Before choosing
the internal representation for a data structure, you need to specify the full
set of operations. In fact, here we only consider <html:code>update</html:code> (associating a
value with an identifier) and <html:code>lookup</html:code> (retrieving such a value). Deletion
is more difficult and would limit our choices. Some applications may need
additional operations, such as <html:code>merge</html:code> (combining two dictionaries). We
shall see that update can be done efficiently in a functional style, without
excessive copying.</html:p>
                    <html:p>An <html:em>abstract type</html:em> provides specified operations while hiding low-level
details, such as the data structure used to represent dictionaries. Abstract
types can be declared in any modern programming language. Java’s <html:em>objects</html:em>
serve this role, as do OCaml’s modules. This course does not cover modules, and we
simply declare the dictionary operations individually.</html:p>
                    <html:p>An <html:em>association list</html:em> (a list of pairs) is the simplest dictionary representation.
Lookup is by <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link>, and therefore slow: <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>. Association lists are
only usable if there are few keys in use. However, they are general in that the
keys do not need a concept of ordering, only equality.</html:p>
                    <html:pre><![CDATA[# exception Missing
exception Missing
# let rec lookup a = function
  | [] -> raise Missing
  | (x, y) :: pairs ->
      if a = x then y
      else lookup a pairs
val lookup : 'a -> ('a * 'b) list -> 'b = <fun>
# let update (l, b, y) = (b, y) :: l
val update : ('a * 'b) list * 'a * 'b -> ('a * 'b) list = <fun>]]></html:pre>
                    <html:p>To enter a new <html:code>(key, value)</html:code> pair, simply “cons” it to the list with <html:code>update</html:code>.
This takes constant time, which is the best we could hope for.  But the space
requirement is huge: linear in the number of updates, not in the number of
distinct keys. Obsolete entries are never deleted: that would require first
finding them, increasing the update time from <fr:tex display="inline"><![CDATA[O(1)]]></fr:tex> to <fr:tex display="inline"><![CDATA[O(n)]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/</fr:uri>
                    <fr:display-uri>focs-equality</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-equality/</fr:route>
                    <fr:title text="Equality Tests">Equality Tests</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec member x = function
   | [] -> false
   | y::l ->
      if x = y then true
      else member x l
val member : 'a -> 'a list -> bool = <fun>]]></html:pre>
                    <html:p>All the list functions we have encountered up to now have been “<fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic</fr:link>”,
working for lists of any type.  Function <html:code>member</html:code> uses <fr:link href="/~avsm2/fcs/focs-linear-search/" title="Linear Search" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-linear-search/" display-uri="focs-linear-search" type="local">linear search</fr:link> to report
whether or not <html:code>x</html:code> occurs in <html:code>l</html:code>.</html:p>
                    <html:p>To do this generically, it uses a special feature of OCaml known as
“polymorphic equality”, which manifests itself via the <html:code>=</html:code>, <html:code>&gt;=</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code> and
<html:code>&lt;</html:code> operators.  These operators inspect the <html:em>structure</html:em> of the values using a
consistent order.  Types you can legitimately compare this way include integers,
strings, booleans, and tuples or lists of primitive types.</html:p>
                    <html:p>More complex types can be compared this way within careful limits: recursive
structures or function values will not work (we will cover function values in
the <fr:link href="/~avsm2/fcs/focs-currying/" title="Curried Functions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/" display-uri="focs-currying" type="local">Currying lecture</fr:link> later).  For now, it is sufficient to use these magic
polymorphic equality operators.  As you get more familiar with OCaml and the
use of <fr:link href="/~avsm2/fcs/focs-functions/" title="Functions as Values" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-functions/" display-uri="focs-functions" type="local">higher order functions</fr:link> (also covered in a later lecture), you will
encounter the use of explicit <html:code>compare</html:code> functions that are used to provide more
complex equality tests.</html:p>
                    <html:p>The presence of polymorphic equality is a contentious feature in OCaml.  While
it provides a great ease of use in smaller codebases, it starts to become more
dangerous when building larger OCaml-based systems.  Most large-scale users of
OCaml tend towards not using it in important code, but it is just fine for our
purposes while learning the beginning steps of computer science.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/</fr:uri>
                    <fr:display-uri>focs-dates</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-dates/</fr:route>
                    <fr:title text="Example 1: Dates">Example 1: Dates</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li><fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">Abstract level</fr:link>: dates over a certain interval</html:li>
  <html:li>Concrete level: could be 6 characters: <html:code>YYMMDD</html:code> (where each character is represented by 8 bits)</html:li>
  <html:li>Date crises caused by <html:strong>inadequate</html:strong> internal formats:
    <html:ul><html:li>Digital’s PDP-10: using 12-bit dates (good for at most 11 years)</html:li>
      <html:li>2000 crisis: 48 bits could be good for lifetime of universe!</html:li></html:ul></html:li></html:ul>
                    <html:p>Digital Equipment Corporation’s date crisis occurred in 1975.  The
PDP-10 was a 36-bit mainframe computer. It represented dates using a 12-bit
format designed for the tiny PDP-8. With 12 bits, one can distinguish
<fr:tex display="inline"><![CDATA[2^{12} = 4096]]></fr:tex> days or 11 years.</html:p>
                    <html:p>Last century, the most common industry format for dates used six characters: two for the
year, two for the month and two for the day. The most common “solution” to the
year 2000 crisis is to add two further characters, thereby altering file sizes.
Others have noticed that the existing six characters consist of 48 bits,
already sufficient to represent all dates over the projected lifetime of the
universe: <fr:tex display="inline"><![CDATA[2^{48}]]></fr:tex> = <fr:tex display="inline"><![CDATA[2.8\times  10^{14}]]></fr:tex> days = <fr:tex display="inline"><![CDATA[7.7\times  10^{11}]]></fr:tex> years!</html:p>
                    <html:p>Mathematicians think in terms of unbounded ranges, but the representation we
choose for the computer usually imposes hard limits. A good programming
language like OCaml lets one easily change the representation used in the
program.  But if files in the old representation exist all over the place,
there will still be conversion problems. The need for compatibility with older
systems causes problems across the computer industry.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/</fr:uri>
                    <fr:display-uri>focs-floating-point</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-floating-point/</fr:route>
                    <fr:title text="Example 2: Floating Point Numbers">Example 2: Floating Point Numbers</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Computers have integers like <html:code>1066</html:code> and floats like <fr:tex display="inline"><![CDATA[1.066\times  10^3]]></fr:tex>.
A floating-point number is represented by two integers.
The concept of <html:em>data type</html:em> involves:</html:p>
                    <html:ul><html:li>how a value is represented inside the computer</html:li>
  <html:li>the suite of operations given to programmers</html:li>
  <html:li>valid and invalid (or exceptional) results, such as “infinity”</html:li></html:ul>
                    <html:p>Computer arithmetic can yield <html:em>incorrect answers!</html:em></html:p>
                    <html:p>In science, numbers written with finite precision and a decimal exponent are
said to be in <html:em>standard form</html:em>. The computational equivalent is the <html:em>floating
point number</html:em>. These are familiar to anybody who has used a scientific
calculator.  Internally, a float consists of two integers.</html:p>
                    <html:p>Because of its finite precision, floating-point computations are potentially
inaccurate. To see an example, use your nearest electronic calculator to
compute <fr:tex display="inline"><![CDATA[(2^{1/10000})^{10000}]]></fr:tex>. I get <fr:tex display="inline"><![CDATA[1.99999959]]></fr:tex>! With certain computations,
the errors spiral out of control. Many programming languages fail to check
whether even integer computations fall within the allowed range: you can add
two positive integers and get a negative one!</html:p>
                    <html:p>Most computers give us a choice of precisions. In 32-bit precision, integers
typically range from <fr:tex display="inline"><![CDATA[2^{31}-1]]></fr:tex> (namely 2 147 483 647) to <fr:tex display="inline"><![CDATA[-2^{31}]]></fr:tex>; floats
are accurate to about six decimal places and can get as large as <fr:tex display="inline"><![CDATA[10^{35}]]></fr:tex> or so.
For floats, 64-bit precision is often preferred. Early languages like Fortran
required variables to be declared as <html:code>INTEGER</html:code>, <html:code>REAL</html:code> or <html:code>COMPLEX</html:code> and barred
programmers from mixing numbers in a computation. Nowadays, programs handle
many different kinds of data, including text and symbols. The concept of a
<html:em>data type</html:em> can ensure that different types of data are not combined in a
senseless way.</html:p>
                    <html:p>Inside the computer, all data are stored as bits. In most programming
languages, the compiler uses types to generate correct machine code, and types
are not stored during program execution. In this course, we focus almost
entirely on programming in a high-level language: OCaml.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-anonymous-functions/</fr:uri>
                    <fr:display-uri>focs-anonymous-functions</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-anonymous-functions/</fr:route>
                    <fr:title text="Functions Without Names">Functions Without Names</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>If functions are to be regarded as computational values, then we need a
notation for them.  The <html:code>fun</html:code> notation expresses a non-recursive function
value without giving the function a name.</html:p>
                    <html:p><fr:tex display="inline"><![CDATA[\tt  fun\;x\;\rightarrow  E]]></fr:tex> is the function <fr:tex display="inline"><![CDATA[f]]></fr:tex> such that <fr:tex display="inline"><![CDATA[f(x)=E]]></fr:tex>.
The function <html:code>fun n -&gt; n*2</html:code> is a <html:em>doubling function</html:em>.</html:p>
                    <html:pre><![CDATA[# fun n -> n * 2
- : int -> int = <fun>
# (fun n -> n * 2) 17
- : int = 34]]></html:pre>
                    <html:p>The main purpose of <html:code>fun</html:code>-notation is to package up small expressions that are to be
applied repeatedly using some other function.
The expression <html:code>fun n -&gt; n*2</html:code> has the same value as the identifier
<html:code>double</html:code>, declared as follows:</html:p>
                    <html:pre><![CDATA[# let double n = n * 2
val double : int -> int = <fun>]]></html:pre>
                    <html:p>The <html:code>fun</html:code> notation can also do <fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern matching</fr:link>, and the <html:code>function</html:code> keyword
adds an anonymous variable name to pattern match against.  The following functions
are all equivalent, with the latter definitions bound to the <html:code>is_zero</html:code> value and the earlier ones anonymous:</html:p>
                    <html:pre><![CDATA[# fun x -> match x with 0 -> true | _ -> false
- : int -> bool = <fun>
# function 0 -> true | _ -> false
- : int -> bool = <fun>
# let is_zero = fun x -> match x with 0 -> true | _ -> false
val is_zero : int -> bool = <fun>
# let is_zero = function 0 -> true | _ -> false
val is_zero : int -> bool = <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/</fr:uri>
                    <fr:display-uri>focs-head-tail</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-head-tail/</fr:route>
                    <fr:title text="Getting at the Head and Tail">Getting at the Head and Tail</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let null = function
    | [] -> true
    | x :: l -> false
val null : 'a list -> bool = <fun>
# null []
- : bool = true
# null [1; 2; 3]
- : bool = false
# let hd (x::l) = x
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val hd : 'a list -> 'a = <fun>
# hd [1; 2; 3]
- : int = 1
# let tl (x::l) = l
Line 1, characters 8-18:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
val tl : 'a list -> 'a list = <fun>
# tl [7; 6; 5]
- : int list = [6; 5]]]></html:pre>
                    <html:p>The empty list has neither head nor tail.  Applying <html:code>hd</html:code> or <html:code>tl</html:code> to <html:code>[]</html:code>
is an error—strictly speaking, an <fr:link href="/~avsm2/fcs/focs-exceptions/" title="Error Handling: Exceptions" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-exceptions/" display-uri="focs-exceptions" type="local">“exception”</fr:link>.  The function <html:code>null</html:code> can
be used to check for the empty list beforehand.  Taking a list apart using
combinations of <html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right.  Fortunately, it is seldom
necessary because of <html:em>pattern-matching</html:em>.</html:p>
                    <html:p>The declaration of <html:code>null</html:code> introduces a new concept known as "pattern matching",
which we will explore more in subsequent lectures. For now, it is sufficient
to observe that <html:code>let null = function</html:code> allows for matching on the two possible values
that might be passed in as argument to <html:code>null</html:code> here: one for the empty list (for which it returns <html:code>true</html:code>)
and one for non-empty lists (for which it returns <html:code>false</html:code>).</html:p>
                    <html:p>The declaration of <html:code>hd</html:code> above has only one clause, for non-empty lists.  They
have the form <html:code>x::l</html:code> and the function returns <html:code>x</html:code>, which is the head.  If you
compile this program, OCaml also prints a warning to tell us that calling
the function could raise an exception because not all possible inputs are handled,
including a counter-example (in this case, the empty list <html:code>[]</html:code>). The declaration of <html:code>tl</html:code> is similar to <html:code>hd</html:code>.</html:p>
                    <html:p>These three primitive functions are <html:em>polymorphic</html:em> and allow flexibility in the
types of their arguments and results. Note their types!</html:p>
                    <html:pre><![CDATA[# null
- : 'a list -> bool = <fun>
# hd
- : 'a list -> 'a = <fun>
# tl
- : 'a list -> 'a list = <fun>]]></html:pre>
                    <html:p>Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type variables</html:em> and stand for any types. Code
written using these functions is checked for type correctness at compile time.
And this guarantees strong properties at run time, for example that the
elements of any list all have the same type.  They are usually read as their
corresponding greek characters; <html:code>'a</html:code> is "alpha", <html:code>'b</html:code> is "beta", and so on.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-goals-of-programming/</fr:uri>
                    <fr:display-uri>focs-goals-of-programming</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-goals-of-programming/</fr:route>
                    <fr:title text="Goals of Programming">Goals of Programming</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>to describe a computation so that it can be done <html:strong>mechanically</html:strong>:
    <html:ul><html:li>Expressions compute values.</html:li>
      <html:li>Commands cause effects.</html:li></html:ul></html:li>
  <html:li>to do so efficiently and <html:strong>correctly</html:strong>, giving the right answers quickly</html:li>
  <html:li>to allow easy modification as needs change
    <html:ul><html:li>Through an orderly <html:strong>structure</html:strong> based on <fr:link href="/~avsm2/fcs/focs-def-abstraction-barrier/" title="Abstraction barrier" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-abstraction-barrier/" display-uri="focs-def-abstraction-barrier" type="local">abstraction principles</fr:link></html:li>
      <html:li>Such as modules or classes</html:li></html:ul></html:li></html:ul>
                    <html:p>Programming <html:em>in-the-small</html:em> concerns the writing of code to do simple, clearly
defined tasks. Programs provide expressions for describing mathematical
formulae and so forth. This was the original contribution of FORTRAN, the
FORmula TRANslator. Commands describe how control should flow from one part of
the program to the next.</html:p>
                    <html:p>As we code layer upon layer, we eventually find ourselves programming
<html:em>in the large</html:em> : joining large modules to solve some messy task. Programming
languages have used various mechanisms to allow one part of the program to
provide interfaces to other parts. Modules encapsulate a body of code, allowing
outside access only through a programmer-defined interface. <fr:link href="/~avsm2/fcs/focs-queue-adt/" title="An Abstract Data Type: Queues" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-queue-adt/" display-uri="focs-queue-adt" type="local"><html:em>Abstract Data
Types</html:em></fr:link> are a simpler version of this concept, which implement a single concept
such as dates or floating-point numbers.</html:p>
                    <html:p><html:em>Object-oriented programming</html:em> is the most complicated approach to modularity.
<html:em>Classes</html:em> define concepts, and they can be built upon other classes. Operations
can be defined that work in appropriately specialised ways on a family of
related classes. <html:em>Objects</html:em> are instances of classes and hold the data that is
being manipulated.</html:p>
                    <html:p>This course does not cover OCaml’s sophisticated module system, which can do
many of the same things as classes. You will learn all about objects when you
study Java. OCaml includes a powerful object system, although this is not used
as much as its module system.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-lazy-ocaml/</fr:uri>
                    <fr:display-uri>focs-lazy-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-lazy-ocaml/</fr:route>
                    <fr:title text="Lazy Lists in OCaml">Lazy Lists in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:ul><html:li>The empty tuple <html:code>()</html:code> and its <html:em>type</html:em> <html:code>unit</html:code></html:li>
  <html:li>Delayed version of <fr:tex display="inline"><![CDATA[E]]></fr:tex> is <html:code>fun () -&gt; E</html:code></html:li></html:ul>
                    <html:pre><![CDATA[# type 'a seq =
  | Nil
  | Cons of 'a * (unit -> 'a seq)
type 'a seq = Nil | Cons of 'a * (unit -> 'a seq)
# let head (Cons (x, _)) = x
Line 1, characters 10-27:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val head : 'a seq -> 'a = <fun>
# let tail (Cons (_, xf)) = xf ()
Line 1, characters 10-32:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Nil
val tail : 'a seq -> 'a seq = <fun>]]></html:pre>
                    <html:p><fr:tex display="inline"><![CDATA[\tt  Cons(x, xf)]]></fr:tex> has <html:em>head</html:em> <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <html:em>tail function</html:em> <fr:tex display="inline"><![CDATA[xf]]></fr:tex></html:p>
                    <html:p>The primitive OCaml type <html:code>unit</html:code> has one element, which is
written <html:code>()</html:code>.  This element may be regarded as a 0-tuple, and
<html:code>unit</html:code> as the nullary Cartesian product.  (Think of the connection
between multiplication and the number 1.)</html:p>
                    <html:p>The empty tuple serves as a placeholder in situations where no information is
required.  It may:</html:p>
                    <html:ul><html:li>appear in a data structure.  For example, a <html:code>unit</html:code>-valued <fr:link href="/~avsm2/fcs/focs-dictionary-adt/" title="Dictionaries" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dictionary-adt/" display-uri="focs-dictionary-adt" type="local">dictionary</fr:link> represents a set of keys.</html:li>
  <html:li>be the argument of a function, where its effect is to <html:em>delay evaluation</html:em>.</html:li>
  <html:li>be the argument or result of a procedure. (see the <fr:link href="/~avsm2/fcs/focs-procedural-programming/" title="Procedural Programming" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-procedural-programming/" display-uri="focs-procedural-programming" type="local">Procedural Programming section</fr:link>)</html:li></html:ul>
                    <html:p>The empty tuple, like all tuples, is a constructor and is allowed in patterns;
for example: <html:code>let f () = ...</html:code></html:p>
                    <html:p>In particular <fr:tex display="inline"><![CDATA[\tt  fun \, () \rightarrow  E]]></fr:tex> is the function that takes an argument of
type <html:code>unit</html:code> and returns the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex> as its result.  Expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>
is not evaluated until the function is called, even though the only possible
argument is <html:code>()</html:code>.  The function simply delays the evaluation of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/</fr:uri>
                    <fr:display-uri>focs-def-mutable-reference</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-mutable-reference/</fr:route>
                    <fr:title text="Mutable reference">Mutable reference</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A reference is a cell in the store, also called a “location”: <html:code>ref E</html:code>
creates a reference with initial contents the value of <html:code>E</html:code>, <html:code>!P</html:code>
returns the current contents of reference <html:code>P</html:code> (an operation called
<html:em>dereferencing</html:em>), and <html:code>P := E</html:code> updates the contents of <html:code>P</html:code> to the
value of <html:code>E</html:code>. If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the
type of references to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.
Introduced in <fr:link href="/~avsm2/fcs/focs-references/" title="OCaml Primitives for References" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/" display-uri="focs-references" type="local">OCaml Primitives for References</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references/</fr:uri>
                    <fr:display-uri>focs-references</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references/</fr:route>
                    <fr:title text="OCaml Primitives for References">OCaml Primitives for References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>Effect</html:th></html:tr>
  <html:tr><html:td><html:code>ref E</html:code></html:td><html:td><html:em>create</html:em> a reference with <html:em>initial contents</html:em> = value of <html:code>E</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!P</html:code></html:td><html:td>return <html:em>current contents</html:em> of reference <html:code>P</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>P := E</html:code></html:td><html:td><html:em>update</html:em> contents of <html:code>P</html:code> to value of <html:code>E</html:code></html:td></html:tr>
</html:table>
                    <html:p>The above text presents the OCaml primitives, but most languages have analogues of
them, often heavily disguised.  We need a means of creating references (or
allocating storage), getting at the current contents of a reference cell, and
updating that cell.</html:p>
                    <html:p>The function <html:code>ref</html:code> creates references (also called
“locations”).  Calling <html:code>ref</html:code> allocates a new location in memory.
Initially, this location holds the value given by
expression <fr:tex display="inline"><![CDATA[E]]></fr:tex>.</html:p>
                    <html:p>The function <html:code>!</html:code>, when applied to a reference, returns its contents.
This operation is called <html:em>dereferencing</html:em>.  Clearly <html:code>!</html:code> is not a
mathematical function; its result depends upon the store.</html:p>
                    <html:p>The assignment <html:code>P:=E</html:code> evaluates expression <fr:tex display="inline"><![CDATA[P]]></fr:tex>, which must return a
reference <fr:tex display="inline"><![CDATA[p]]></fr:tex>, and <fr:tex display="inline"><![CDATA[E]]></fr:tex>.  It stores at address <fr:tex display="inline"><![CDATA[p]]></fr:tex> the value of <fr:tex display="inline"><![CDATA[E]]></fr:tex>.
Syntactically, <html:code>:=</html:code> is a function and <html:code>P:=E</html:code> is an
expression, even though it updates the store.  Like many functions that change
the state, it returns the value <html:code>()</html:code> of type <html:code>unit</html:code>.</html:p>
                    <html:p>If <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> is some OCaml type, then <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex> <html:code>ref</html:code> is the type of references
to cells that can hold values of <fr:tex display="inline"><![CDATA[\tau ]]></fr:tex>.  Please do not confuse the type
<html:code>ref</html:code> with the function <html:code>ref</html:code>.  This table of the primitive
functions and their types might be useful:</html:p>
                    <html:table>
  <html:tr><html:th>Syntax</html:th><html:th>OCaml Type</html:th></html:tr>
  <html:tr><html:td><html:code>ref</html:code></html:td><html:td><html:code>'a -&gt; 'a ref</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>!</html:code></html:td><html:td><html:code>'a ref -&gt; 'a</html:code></html:td></html:tr>
  <html:tr><html:td><html:code>:=</html:code></html:td><html:td><html:code>'a ref -&gt; 'a -&gt; unit</html:code></html:td></html:tr>
</html:table>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/</fr:uri>
                    <fr:display-uri>focs-def-pattern-matching</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-pattern-matching/</fr:route>
                    <fr:title text="Pattern matching">Pattern matching</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Pattern matching takes a value apart by matching it against the forms that
value can have, letting <html:em>one</html:em> function declaration handle several cases,
separated by a vertical bar <html:code>|</html:code>. Taking a list apart using combinations of
<html:code>hd</html:code> and <html:code>tl</html:code> is hard to get right; fortunately, it is seldom necessary
because of pattern-matching.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/</fr:uri>
                    <fr:display-uri>focs-def-polymorphism</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-def-polymorphism/</fr:route>
                    <fr:title text="Polymorphism">Polymorphism</fr:title>
                    <fr:taxon>Definition</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A polymorphic function allows flexibility in the types of its arguments and
results: the list primitives <html:code>null</html:code>, <html:code>hd</html:code> and <html:code>tl</html:code> work whatever
the element type is. Symbols <html:code>'a</html:code> and <html:code>'b</html:code> are called <html:em>type
variables</html:em> and stand for any types, and code written using them is still checked
for type correctness at compile time.
Introduced in <fr:link href="/~avsm2/fcs/focs-head-tail/" title="Getting at the Head and Tail" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-head-tail/" display-uri="focs-head-tail" type="local">Getting at the Head and Tail</fr:link>.</html:p>
                    <html:p>Part of the course <fr:link href="/~avsm2/fcs/focs-glossary/" title="Glossary" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-glossary/" display-uri="focs-glossary" type="local">glossary</fr:link>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/</fr:uri>
                    <fr:display-uri>focs-npower</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-npower/</fr:route>
                    <fr:title text="Raising a Number to a Power">Raising a Number to a Power</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let rec npower x n =
    if n = 0 then 1.0
    else x *. npower x (n - 1)
val npower : float -> int -> float = <fun>]]></html:pre>
                    <html:p>Our new <html:code>npower</html:code> definition can now take additional arguments, reflected in the arrows
present in the type of <html:code>npower</html:code>; these represent <html:em>parameters</html:em> that can be passed to the
new value being defined, with the final segment being the resulting type. Thus our <html:code>npower</html:code>
type can be read as "pass in a float and integer to return a float".</html:p>
                    <html:p><html:em>Mathematical Justification</html:em> (for <fr:tex display="inline"><![CDATA[x\not =0]]></fr:tex>):</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
           x^0 & = 1 \\
           x^{n+1} & = x\times  x^n.
\end {aligned}
]]></fr:tex>
                    <html:p>The function <html:code>npower</html:code> raises its float argument <html:code>x</html:code> to the power <html:code>n</html:code>, a
non-negative integer. The function is <html:strong>recursive</html:strong>: it calls itself.  You
can spot a recursive function due to the <html:code>rec</html:code> keyword in the definition:
this indicates that any invocation of the function name within the function body should call itself.
This concept should be familiar from mathematics, since exponentiation is defined by the
rules shown above. You may also have seen recursion in the product rule for
differentiation: <fr:tex display="inline"><![CDATA[(u\cdot  v)' = u\cdot  v' + u'\cdot  v]]></fr:tex>. In finding the derivative of <fr:tex display="inline"><![CDATA[u\cdot  v]]></fr:tex>,
we recursively find the derivatives of <fr:tex display="inline"><![CDATA[u]]></fr:tex> and <fr:tex display="inline"><![CDATA[v]]></fr:tex>, combining them to obtain the desired result.
The recursion is meaningful because it terminates: we reduce the problem to two smaller
problems, and this cannot go on forever. The OCaml programmer uses recursion
heavily.  For <fr:tex display="inline"><![CDATA[n\geq 0]]></fr:tex>, the equation <fr:tex display="inline"><![CDATA[x^{n+1} = x\times  x^n]]></fr:tex> yields an obvious
computation:</html:p>
                    <fr:tex display="block"><![CDATA[ x^3 = x\times  x^2 = x\times  x\times  x^1 = x\times  x\times  x\times  x^0 = x\times  x\times  x ]]></fr:tex>
                    <html:p>The equation clearly holds even for negative <fr:tex display="inline"><![CDATA[n]]></fr:tex>. However, the corresponding
computation runs forever:</html:p>
                    <fr:tex display="block"><![CDATA[ x^{-1} = x\times  x^{-2} = x\times  x\times  x^{-3}=\cdots  ]]></fr:tex>
                    <html:p>Note that the function <html:code>npower</html:code> contains both an integer constant (<html:code>0</html:code>) and a
floating point constant (<html:code>1.0</html:code>). The decimal point makes all the difference.
OCaml will notice and ascribe different meaning to each type of constant.</html:p>
                    <html:pre><![CDATA[# let square x = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>Now for a tiresome but necessary aside. In most languages, the types of
arguments and results must always be specified. OCaml is unusual that it normally
infers the types itself. However, sometimes it is useful to supply a hint to
help you debug and develop your program. OCaml will still infer the types even if you don’t specify them, but in some cases
it will use a more inefficient function than a specialised one. Some languages
have just one type of number, converting automatically between different
formats; this is slow and could lead to unexpected rounding errors.  Type
constraints are allowed almost anywhere. We can put one on any occurrence of x
in the function.</html:p>
                    <html:pre><![CDATA[# let square (x : float) = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>Or we can constrain the type of the function’s result:</html:p>
                    <html:pre><![CDATA[# let square x : float = x *. x
val square : float -> float = <fun>]]></html:pre>
                    <html:p>OCaml treats the equality and comparison test specially. Expressions like <html:code>if x = y then</html:code> …
are allowed provided <html:code>x</html:code> and <html:code>y</html:code> have the same type and equality testing is
possible for that type. (We discuss <fr:link href="/~avsm2/fcs/focs-equality/" title="Equality Tests" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-equality/" display-uri="focs-equality" type="local">equality</fr:link> further in a later lecture.)
Note that <html:code>x &lt;&gt; y</html:code> is OCaml for <fr:tex display="inline"><![CDATA[x\not =y]]></fr:tex>.</html:p>
                    <html:p>A characteristic feature of the computer is its ability to test for conditions
and act accordingly.  In the early days, a program might jump to a given
address depending on the sign of some number.  Later, John McCarthy defined
the <html:em>conditional expression</html:em> to satisfy <html:code>if true then x else y = x</html:code> and
<html:code>if false then x else y = y</html:code>.</html:p>
                    <html:p>OCaml evaluates the expression <html:code>if</html:code> <fr:tex display="inline"><![CDATA[B]]></fr:tex> <html:code>then</html:code> <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> <html:code>else</html:code> <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> by first evaluating <fr:tex display="inline"><![CDATA[B]]></fr:tex>.
If the result is <html:code>true</html:code> then OCaml evaluates <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and otherwise <fr:tex display="inline"><![CDATA[E_2]]></fr:tex>.  Only one
of the two expressions <fr:tex display="inline"><![CDATA[E_1]]></fr:tex> and <fr:tex display="inline"><![CDATA[E_2]]></fr:tex> is evaluated!  If both were evaluated,
then recursive functions like <html:code>npower</html:code> above would run forever.</html:p>
                    <html:p>The <html:code>if</html:code>-expression is governed by an expression of type <html:code>bool</html:code>, whose two
values are <html:code>true</html:code> and <html:code>false</html:code>.  In modern programming languages, tests are not
built into “conditional branch” constructs but can just be part of normal expressions.
Tests, or <html:em>Boolean expressions,</html:em> can be expressed using relational operators
such as <html:code>&lt;</html:code> and <html:code>=</html:code>. They can be combined using the Boolean operators for
negation (<html:code>not</html:code>), conjunction (written as <html:code>&amp;&amp;</html:code>) and disjunction (written as <html:code>||</html:code>).  New
properties can be declared as functions: here, to test whether an integer is
even, for example:</html:p>
                    <html:pre><![CDATA[# let even n = n mod 2 = 0
val even : int -> bool = <fun>]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-references-examples/</fr:uri>
                    <fr:display-uri>focs-references-examples</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-references-examples/</fr:route>
                    <fr:title text="Trying Out References">Trying Out References</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:pre><![CDATA[# let p = ref 5 (* create a reference *)
val p : int ref = {contents = 5}
# p := !p + 1   (* p now holds value 6 *)
- : unit = ()
# let ps = [ ref 77; p ]
val ps : int ref list = [{contents = 77}; {contents = 6}]
# List.hd ps := 3
- : unit = ()
# ps
- : int ref list = [{contents = 3}; {contents = 6}]]]></html:pre>
                    <html:p>The first line declares <html:code>p</html:code> to hold a <fr:link href="/~avsm2/fcs/focs-def-mutable-reference/" title="Mutable reference" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-mutable-reference/" display-uri="focs-def-mutable-reference" type="local">reference</fr:link> to an integer,
initially 5.  Its type is <html:code>int ref</html:code>, not just <html:code>int</html:code>, so it
admits assignment.  Assignment never changes <html:code>let</html:code> bindings: they are
<html:em>immutable</html:em>.  The identifier <html:code>p</html:code> will always denote the reference
mentioned in its declaration unless superseded by a new usage of <html:code>p</html:code>.
Only the <html:em>contents</html:em> of the reference is mutable.</html:p>
                    <html:p>OCaml displays a reference value as <html:code><![CDATA[{contents=v}]]></html:code>, where value <fr:tex display="inline"><![CDATA[v]]></fr:tex> is the
contents.  This notation is readable but gives us no way of telling whether
two references holding the same value are actually the same reference.  To
display a reference as a machine address has obvious drawbacks!</html:p>
                    <html:p>In the first assignment, the expression <html:code>!p</html:code> yields the reference’s
current contents, namely 5.  The assignment changes the contents of <html:code>p</html:code>
to 6.  Most languages do not have an explicit dereferencing operator
(like <html:code>!</html:code>) because of its inconvenience.  Instead, by convention,
occurrences of the reference on the <html:em>left-hand</html:em> side of the <html:code>:=</html:code>
denote locations and those on the <html:em>right-hand</html:em> side denote the contents.
A special ‘address of’ operator may be available to override the convention
and make a reference on the right-hand side to denote a location.  Logically
this is a mess, but it makes programs shorter.</html:p>
                    <html:p>The list <html:code>ps</html:code> is declared to hold a new reference (initially
containing 77) as well as <html:code>p</html:code>.  Then the new reference is
updated to hold 3.  The assignment to <html:code>hd ps</html:code> does <html:em>not</html:em>
update <html:code>ps</html:code>, only the contents of a reference in that list.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-why-ocaml/</fr:uri>
                    <fr:display-uri>focs-why-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-why-ocaml/</fr:route>
                    <fr:title text="Why Program in OCaml?">Why Program in OCaml?</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Why program in OCaml at all?</html:p>
                    <html:ul><html:li>It is interactive.</html:li>
  <html:li>It has a flexible notion of <html:em>data type</html:em>.</html:li>
  <html:li>It hides the underlying hardware: <html:em>no crashes</html:em>.</html:li>
  <html:li>Programs can easily be understood mathematically.</html:li>
  <html:li>It distinguishes naming something from <html:em>updating memory</html:em>.</html:li>
  <html:li>It manages storage for us.</html:li></html:ul>
                    <html:p>Programming languages matter. They affect the reliability, security, and
efficiency of the code you write, as well as how easy it is to read, refactor,
and extend. The languages you know can also change how you think, influencing
the way you design software even when you’re not using them.</html:p>
                    <html:p>What makes OCaml special is that it occupies a sweet spot in the space of
programming language designs. It provides a combination of efficiency,
expressiveness and practicality that is difficult to find matched by any other language.
“ML” was originally the meta language of the LCF (Logic for Computable Functions)
proof assistant released by Robin Milner in 1972 (at Stanford, and later at Cambridge).
ML was turned into a compiler in order to make it easier to use LCF on different machines,
and it was gradually turned into a full-fledged system of its own by the 1980s.</html:p>
                    <html:p>The modern OCaml emerged in 1996, and the past twenty five years have seen OCaml
attract a significant user base with language improvements being steadily
added to support the growing commercial and academic codebases.
OCaml is therefore the outcome of years of research into programming languages,
and a good base to begin our journey into learning the foundations of computer
science.</html:p>
                    <html:p>Because of its connection to mathematics, OCaml programs can be designed and
understood without thinking in detail about how the computer will run them.
Although a program can abort, it cannot crash: it remains under the control of
the OCaml system. It still achieves respectable efficiency and provides
lower-level primitives for those who need them. Most other languages allow
direct access to the underlying machine and even try to execute illegal
operations, causing crashes.</html:p>
                    <html:p>The only way to learn programming is by writing and running programs. This web
notebook provides an interactive environment where you can modify the example
fragments and see the results for yourself.  You should also consider
installing OCaml on your own computer so that you try more advanced programs
locally.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-3/</fr:uri>
                    <fr:display-uri>focs-ex-4-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-3/</fr:route>
                    <fr:title text="Exercises › A non-exhaustive zip"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › A non-exhaustive zip</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>How does this version of <html:code>zip</html:code> differ from <fr:link href="/~avsm2/fcs/focs-zip/" title="Building a List of Pairs" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-zip/" display-uri="focs-zip" type="local">the one above</fr:link>?</html:p>
                    <html:pre><![CDATA[let rec zip xs ys =
  match xs, ys with
  | (x::xs, y::ys) -> (x, y) :: zip xs ys
  | ([], [])   -> []]]></html:pre>
                    <html:pre><![CDATA[Lines 2-4, characters 5-23:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(_::_, [])]]></html:pre>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-4/</fr:uri>
                    <fr:display-uri>focs-ex-6-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-4/</fr:route>
                    <fr:title text="Exercises › A type for arithmetic expressions"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › A type for arithmetic expressions</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Give the declaration of an OCaml type for arithmetic expressions that have the following
possibilities: floating-point numbers, variables (represented by strings), or expressions of the form <fr:tex display="inline"><![CDATA[-E]]></fr:tex>,
<fr:tex display="inline"><![CDATA[E+E]]></fr:tex>, <fr:tex display="inline"><![CDATA[E\times  E]]></fr:tex>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-2/</fr:uri>
                    <fr:display-uri>focs-ex-1-2</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-2/</fr:route>
                    <fr:title text="Exercises › Comparing and adding years"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Comparing and adding years</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Using the date representation of <fr:link href="/~avsm2/fcs/focs-ex-1-1/" title="Exercises › Two-digit year windowing" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/" display-uri="focs-ex-1-1" type="local">the previous exercise</fr:link>, code OCaml functions to (a) compare two
years (b) add/subtract some given number of years from another year.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6-1/</fr:uri>
                    <fr:display-uri>focs-ex-6-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-6-1/</fr:route>
                    <fr:title text="Exercises › Days of the week type"><fr:link href="/~avsm2/fcs/focs-ex-6/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-6/" display-uri="focs-ex-6" type="local">Exercises</fr:link> › Days of the week type</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Give the declaration of an OCaml type for the days of the week. Comment on the practicality of such
a type in a calendar application.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-5/</fr:uri>
                    <fr:display-uri>focs-ex-1-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-5/</fr:route>
                    <fr:title text="Exercises › Floating-point error by repeated addition"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Floating-point error by repeated addition</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Because computer arithmetic is based on binary numbers, simple decimals such as 0.1 often cannot be
represented exactly. Write a function <html:code>mul</html:code> that performs the computation</html:p>
                    <fr:tex display="block"><![CDATA[\underbrace {x+x+\cdots +x}_{n}]]></fr:tex>
                    <html:p>where <fr:tex display="inline"><![CDATA[x]]></fr:tex> has type <html:code>float</html:code>. (It is essential to use repeated addition rather than multiplication!)</html:p>
                    <html:p>The value computed with <html:code>n = 10000</html:code> and <html:code>x = 0.1</html:code> may print as
<html:code>1000.0</html:code>, which looks exact. If that happens, then evaluate the
expression <html:code>mul 0.1 10000 -. 1000.0</html:code></html:p>
                    <html:p>An error of this type has been blamed for the failure of an American Patriot Missile battery to
intercept an incoming Iraqi missile during the <fr:link href="https://en.wikipedia.org/wiki/MIM-104_PatriotFailure_at_Dhahran" type="external">first Gulf War</fr:link>.
The missile hit an American Army barracks, killing 28.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-6/</fr:uri>
                    <fr:display-uri>focs-ex-1-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-6/</fr:route>
                    <fr:title text="Exercises › Golden ratio instability"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Golden ratio instability</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Another example of the <fr:link href="/~avsm2/fcs/focs-floating-point/" title="Example 2: Floating Point Numbers" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-floating-point/" display-uri="focs-floating-point" type="local">inaccuracy of floating-point arithmetic</fr:link> takes the golden ratio
<fr:tex display="inline"><![CDATA[\phi \approx 1.618\ldots ]]></fr:tex> as its starting point:</html:p>
                    <fr:tex display="block"><![CDATA[\gamma _0 = \frac {1+\sqrt 5}{2} \quad \text {and}\quad \gamma _{n+1} = \frac {1}{\gamma _n-1}.]]></fr:tex>
                    <html:p>In theory, it is easy to prove that <fr:tex display="inline"><![CDATA[\gamma _n=\cdots  = \gamma _1 = \gamma _0]]></fr:tex> for all <fr:tex display="inline"><![CDATA[n>0]]></fr:tex>. Code this
computation in OCaml and report the value of <fr:tex display="inline"><![CDATA[\gamma _{50}]]></fr:tex>. <html:em>Hint:</html:em> in OCaml, <fr:tex display="inline"><![CDATA[\sqrt 5]]></fr:tex> is expressed
as <html:code>sqrt 5.0</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-1/</fr:uri>
                    <fr:display-uri>focs-ex-11-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-1/</fr:route>
                    <fr:title text="Exercises › Lists of references"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Lists of references</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Comment, with examples, on the differences between an <html:code>int ref list</html:code> and an <html:code>int list ref</html:code>.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3-4/</fr:uri>
                    <fr:display-uri>focs-ex-3-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-3-4/</fr:route>
                    <fr:title text="Exercises › Polymorphic types of id and loop"><fr:link href="/~avsm2/fcs/focs-ex-3/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-3/" display-uri="focs-ex-3" type="local">Exercises</fr:link> › Polymorphic types of id and loop</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Consider the <fr:link href="/~avsm2/fcs/focs-def-polymorphism/" title="Polymorphism" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-polymorphism/" display-uri="focs-def-polymorphism" type="local">polymorphic types</fr:link> in these two function declarations:</html:p>
                    <html:pre><![CDATA[# let id x = x
val id : 'a -> 'a = <fun>
# let rec loop x = loop x
val loop : 'a -> 'b = <fun>]]></html:pre>
                    <html:p>Explain why these types make logical sense, preventing run time type errors, even for expressions
like <html:code>id [id [id 0]]</html:code> or <html:code>loop true / loop 3</html:code>. (<html:code>/</html:code> is the integer division operator in OCaml)</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4-6/</fr:uri>
                    <fr:display-uri>focs-ex-4-6</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-4-6/</fr:route>
                    <fr:title text="Exercises › Reasoning from polymorphic types"><fr:link href="/~avsm2/fcs/focs-ex-4/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-4/" display-uri="focs-ex-4" type="local">Exercises</fr:link> › Reasoning from polymorphic types</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>We know nothing about the functions <html:code>f</html:code> and <html:code>g</html:code> other than their polymorphic types:
<html:code>val f : 'a * 'b -&gt; 'b * 'a</html:code> and <html:code>val g : 'a -&gt; 'a list</html:code>.
Suppose that <html:code>f (1, true)</html:code> and <html:code>g 0</html:code> are evaluated and return their results. State, with reasons,
what you think the resulting values will be.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-3/</fr:uri>
                    <fr:display-uri>focs-ex-1-3</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-3/</fr:route>
                    <fr:title text="Exercises › Redundant conditionals"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Redundant conditionals</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Why would no experienced programmer write an expression of the form <html:code>if</html:code> … <html:code>then true else false</html:code>?
What about expressions of the form <html:code>if</html:code> … <html:code>then false else true</html:code>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-1/</fr:uri>
                    <fr:display-uri>focs-ex-1-1</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-1/</fr:route>
                    <fr:title text="Exercises › Two-digit year windowing"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Two-digit year windowing</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>One solution to the <fr:link href="/~avsm2/fcs/focs-dates/" title="Example 1: Dates" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-dates/" display-uri="focs-dates" type="local">year 2000 bug</fr:link> involves storing years as two digits, but interpreting them such
that 50 means 1950 and 49 means 2049. Comment on the merits and demerits of this approach.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1-4/</fr:uri>
                    <fr:display-uri>focs-ex-1-4</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-1-4/</fr:route>
                    <fr:title text="Exercises › Type inference in power"><fr:link href="/~avsm2/fcs/focs-ex-1/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-1/" display-uri="focs-ex-1" type="local">Exercises</fr:link> › Type inference in power</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Functions <fr:link href="/~avsm2/fcs/focs-npower/" title="Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-npower/" display-uri="focs-npower" type="local"><html:code>npower</html:code></fr:link> and <fr:link href="/~avsm2/fcs/focs-power/" title="Efficiently Raising a Number to a Power" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-power/" display-uri="focs-power" type="local"><html:code>power</html:code></fr:link> both return a <html:code>float</html:code>. The definition of <html:code>npower</html:code> returns the float
value <html:code>1.0</html:code> in its base case. The definition of <html:code>power</html:code> does not, so how does the OCaml type checker
know that <html:code>power</html:code> returns a <html:code>float</html:code>?</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-strings/</fr:uri>
                <fr:display-uri>focs-topic-strings</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-strings/</fr:route>
                <fr:title text="Strings">Strings</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-currying/</fr:uri>
                    <fr:display-uri>focs-currying</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-currying/</fr:route>
                    <fr:title text="Curried Functions">Curried Functions</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>A <html:em>curried function</html:em> returns another function as its result. We use
the string concetenation operator <html:code>(^)</html:code> to illustrate how this works.</html:p>
                    <html:pre><![CDATA[# (^)
- : string -> string -> string = <fun>
# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let promote = prefix "Senior "
val promote : string -> string = <fun>
# prefix "Junior " "Professor"
- : string = "Junior Professor"
# promote "Professor"
- : string = "Senior Professor"]]></html:pre>
                    <html:p>A short form for the definition of <html:code>prefix</html:code> is simply to pass multiple
arguments to the function definition.  The following two definitions
are equivalent in OCaml:</html:p>
                    <html:pre><![CDATA[# let prefix = fun a -> fun b -> a ^ b
val prefix : string -> string -> string = <fun>
# let prefix a b = a ^ b
val prefix : string -> string -> string = <fun>]]></html:pre>
                    <html:p>Currying is the technique of expressing a function taking multiple arguments as nested functions, each taking a single argument.
The <html:code>fun</html:code>-notation lets us package <html:code>n*2</html:code> as the function
<html:code>fun n -&gt; n * 2</html:code>, but what if there are several variables, as in
<html:code>fun n -&gt; n * 2 + k</html:code>?  A function of two arguments could be coded using
<fr:link href="/~avsm2/fcs/focs-def-pattern-matching/" title="Pattern matching" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-pattern-matching/" display-uri="focs-def-pattern-matching" type="local">pattern-matching</fr:link> on pairs, writing <html:code>fun (n, k) -&gt; n * 2 + k</html:code>.</html:p>
                    <html:p>Currying is an alternative, where we <html:em>nest</html:em> the <html:code>fun</html:code>-notation:</html:p>
                    <html:pre><![CDATA[# fun k -> fun n -> n * 2 + k
- : int -> int -> int = <fun>]]></html:pre>
                    <html:p>Applying this curried function to the argument 1 yields another function, in which <html:code>k</html:code> has been replaced by 1:</html:p>
                    <html:pre><![CDATA[# let fn = fun k -> fun n -> n * 2 + k
val fn : int -> int -> int = <fun>
# let fn' = fn 1 (* n * 2 + 1 *)
val fn' : int -> int = <fun>
# fn' 3  (* 3 * 2 + 1 *)
- : int = 7]]></html:pre>
                    <html:p>And this function, when applied to 3, yields the result 7. The two arguments are supplied one after another.</html:p>
                    <html:p>The example on the slide is similar but refers to the expression <html:code>a^b</html:code>,
where <html:code>^</html:code> is the infix operator for string concatenation. Function <html:code>promote</html:code> binds the first argument of <html:code>prefix</html:code> to
<html:code>"Professor"</html:code>; the resulting function prefixes that title
to any string to which it is applied.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-strings-chars/</fr:uri>
                    <fr:display-uri>focs-strings-chars</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-strings-chars/</fr:route>
                    <fr:title text="Lists, Strings and Characters">Lists, Strings and Characters</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Strings are provided in most programming languages to allow text processing.
Strings are essential for communication with users. Even a purely numerical
program formats its results ultimately as strings.</html:p>
                    <html:pre><![CDATA[# 'a'   (* a character constant *)
- : char = 'a'
# "a"   (* a string constant of length 1 *)
- : string = "a"
# "abc" (* a string constant of length 3 *)
- : string = "abc"
# String.length "abc"
- : int = 3
# "abc" ^ "def"  (* concatenate two strings *)
- : string = "abcdef"]]></html:pre>
                    <html:p>In a few programming languages, strings simply are lists of characters. In
OCaml they are a separate type, unrelated to lists, reflecting the fact that
strings are an abstract concept in themselves.</html:p>
                    <html:p>Similarly, characters are not strings of size one, but are a primitive concept.
Character constants in OCaml have the form <html:code>'c'</html:code>, where <fr:tex display="inline"><![CDATA[c]]></fr:tex> is any character.
For example, the comma character is <html:code>','</html:code>.</html:p>
                    <html:p>Special characters are coded in strings using <html:em>escape sequences</html:em> involving the
backslash character; among many others, a double quote is written <html:code><![CDATA["\\"]]></html:code> and
the newline character is written <html:code><![CDATA["\n"]]></html:code>. For example, the string
<html:code><![CDATA["I\nLIKE\nCHEESE\n"]]></html:code> represents three text lines.</html:p>
                    <html:p>In addition to the operators described above, the relations <html:code>&lt;</html:code>, <html:code>&lt;=</html:code>, <html:code>&gt;</html:code>, and
<html:code>&gt;=</html:code> work for strings and yield alphabetic order (more precisely, lexicographic
order with respect to ASCII character codes).</html:p>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors>
                  <fr:author>
                    <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                  </fr:author>
                </fr:authors>
                <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-topic-matrices/</fr:uri>
                <fr:display-uri>focs-topic-matrices</fr:display-uri>
                <fr:route>/~avsm2/fcs/focs-topic-matrices/</fr:route>
                <fr:title text="Matrices">Matrices</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/</fr:uri>
                    <fr:display-uri>focs-transpose</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-transpose/</fr:route>
                    <fr:title text="Example: Matrix Transpose">Example: Matrix Transpose</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {pmatrix}
           a   & b & c \\
           d   & e & f
   \end {pmatrix}^T =
   \begin {pmatrix}
        a & d     \\
        b & e     \\
        c & f
\end {pmatrix}
]]></fr:tex>
                    <html:pre><![CDATA[# let rec transp = function
    | []::_ -> []
    | rows -> (map List.hd rows) ::
              (transp (map List.tl rows))
val transp : 'a list list -> 'a list list = <fun>]]></html:pre>
                    <html:p>A matrix can be viewed as a list of rows, each row a list of matrix elements.
This representation is not especially efficient compared with the conventional
one (using arrays).  Lists of lists turn up often, though, and we can see how
to deal with them by taking familiar matrix operations as examples.
<html:em>ML for the Working Programmer</html:em> goes as far as Gaussian elimination,
which presents surprisingly few difficulties.</html:p>
                    <html:p>The transpose of the matrix
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix} a & b & c \\
                           d & e & f\end {smallmatrix}\right )]]></fr:tex>
is
<fr:tex display="inline"><![CDATA[\left (\begin {smallmatrix}
        a & d     \\
        b & e     \\
        c & f
   \end {smallmatrix}\right )]]></fr:tex>,
which in OCaml corresponds to the following transformation on lists of lists:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {[[a; b; c]; [d; e; f]]} \Rightarrow & \text { [[a; d]; [b; e]; [c; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>The workings of function <html:code>transp</html:code> are simple.  If <html:code>rows</html:code> is the
matrix to be transposed, then <html:code>map hd</html:code> extracts its first column and
<html:code>map tl</html:code> extracts its second column:</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {aligned}
\text {map hd rows} \Rightarrow  & \text { [a; d]}\\
\text {map tl rows} \Rightarrow  & \text { [[b; c]; [e; f]]}
\end {aligned}
]]></fr:tex>
                    <html:p>A recursive call transposes the latter matrix, which is then given the column
<html:code>[a; d]</html:code> as its first row.
The two functions expressed using <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> would otherwise have to be declared
separately.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matmul-ocaml/</fr:uri>
                    <fr:display-uri>focs-matmul-ocaml</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-matmul-ocaml/</fr:route>
                    <fr:title text="Matrix Multiplication in OCaml">Matrix Multiplication in OCaml</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p><html:em>Dot product</html:em> of two vectors—a <html:em><fr:link href="/~avsm2/fcs/focs-def-currying/" title="Currying" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-currying/" display-uri="focs-def-currying" type="local">curried function</fr:link></html:em></html:p>
                    <html:pre><![CDATA[# let rec dotprod xs ys =
    match xs, ys with
    | [], [] -> 0.0
    | x::xs, y::ys ->  (x *. y) +. (dotprod xs ys)
Lines 2-4, characters 5-51:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
([], _::_)
val dotprod : float list -> float list -> float = <fun>]]></html:pre>
                    <html:p>
                      <html:em>Matrix product</html:em>
                    </html:p>
                    <html:pre><![CDATA[# let rec matprod arows brows =
    let cols = transp brows in
    map (fun row -> map (dotprod row) cols) arows
val matprod : float list list -> float list list -> float list list = <fun>]]></html:pre>
                    <html:p>The <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local"><html:code>transp brows</html:code></fr:link> converts <fr:tex display="inline"><![CDATA[B]]></fr:tex> into a list of columns, yielding a
list whose elements are the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Each row of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is
obtained by multiplying a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex> by the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
                    <html:p>Because <html:code>dotprod</html:code> is curried, it can be applied to a row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The
resulting function is applied to all the columns of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  We have another
example of currying and partial application.</html:p>
                    <html:p>The outer <fr:link href="/~avsm2/fcs/focs-map/" title="map: the “Apply to All” Function" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-map/" display-uri="focs-map" type="local"><html:code>map</html:code></fr:link> applies <html:code>dotprod</html:code> to each row of <fr:tex display="inline"><![CDATA[A]]></fr:tex>.  The inner
<html:code>map</html:code>, using <html:code>fun</html:code>-notation, applies <html:code>dotprod row</html:code> to each
column of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.  Compare with the version in <html:em>ML for the Working
  Programmer</html:em> (page 89) which does not use <html:code>map</html:code> and requires two
additional function declarations.</html:p>
                    <html:p>In the dot product function, the two vectors must have the same length.
Otherwise, <fr:link href="/~avsm2/fcs/focs-def-exception/" title="Exception" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-def-exception/" display-uri="focs-def-exception" type="local">exception</fr:link> <html:code>Match_failure</html:code> is raised.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-matrix-multiplication/</fr:uri>
                    <fr:display-uri>focs-matrix-multiplication</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-matrix-multiplication/</fr:route>
                    <fr:title text="Review of Matrix Multiplication">Review of Matrix Multiplication</fr:title>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tex display="block"><![CDATA[
\begin {pmatrix} A_1 & \cdots  & A_k \end {pmatrix}  \cdot 
   \begin {pmatrix}
        B_1 \\ \vdots  \\ B_k
   \end {pmatrix}   =
   \begin {pmatrix}
        A_1 B_1 + \cdots  + A_k B_k
   \end {pmatrix}
]]></fr:tex>
                    <html:p>The right side is the <html:em>vector dot product</html:em> <fr:tex display="inline"><![CDATA[\vec {A}\cdot  \vec {B}]]></fr:tex>.
Repeat for each <html:em>row</html:em> of <fr:tex display="inline"><![CDATA[A]]></fr:tex> and <html:em>column</html:em> of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
                    <html:p>The <html:em>dot product</html:em> of two vectors is</html:p>
                    <fr:tex display="block"><![CDATA[ (a_1,\ldots ,a_k) \cdot  (b_1,\ldots ,b_k) = a_1b_1 + \cdots  + a_kb_k ]]></fr:tex>
                    <html:p>A simple case of matrix multiplication is when <fr:tex display="inline"><![CDATA[A]]></fr:tex> consists of a single row
and <fr:tex display="inline"><![CDATA[B]]></fr:tex> consists of a single column.  Provided <fr:tex display="inline"><![CDATA[A]]></fr:tex> and <fr:tex display="inline"><![CDATA[B]]></fr:tex> contain the same
number <fr:tex display="inline"><![CDATA[k]]></fr:tex> of elements, multiplying them yields a <fr:tex display="inline"><![CDATA[1\times 1]]></fr:tex> matrix whose
single element is the dot product shown above.</html:p>
                    <html:p>If <fr:tex display="inline"><![CDATA[A]]></fr:tex> is an <fr:tex display="inline"><![CDATA[m\times  k]]></fr:tex> matrix and <fr:tex display="inline"><![CDATA[B]]></fr:tex> is a <fr:tex display="inline"><![CDATA[k\times  n]]></fr:tex> matrix
then <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix.
For each <fr:tex display="inline"><![CDATA[i]]></fr:tex> and <fr:tex display="inline"><![CDATA[j]]></fr:tex>, the <fr:tex display="inline"><![CDATA[(i,j)]]></fr:tex> element of <fr:tex display="inline"><![CDATA[A\times  B]]></fr:tex> is the dot
product of row <fr:tex display="inline"><![CDATA[i]]></fr:tex> of <fr:tex display="inline"><![CDATA[A]]></fr:tex> with column <fr:tex display="inline"><![CDATA[j]]></fr:tex> of <fr:tex display="inline"><![CDATA[B]]></fr:tex>.</html:p>
                    <fr:tex display="block"><![CDATA[
\begin {pmatrix}
        2 & 0 \\
        3 &-1 \\
        0 & 1 \\
        1 & 1
   \end {pmatrix}
   \begin {pmatrix}
        1 & 0 & 2 \\
        4 &-1 & 0
   \end {pmatrix}   =
   \begin {pmatrix}
        2 & 0 & 4 \\
       -1 & 1 & 6 \\
        4 &-1 & 0 \\
        5 &-1 & 2
\end {pmatrix}
]]></fr:tex>
                    <html:p>The (1, 1) element above is computed by</html:p>
                    <fr:tex display="block"><![CDATA[ (2,0)\cdot (1,4) = 2\times 1 + 0\times 4 = 2. ]]></fr:tex>
                    <html:p>Coding matrix multiplication in a conventional programming language usually
involves three nested loops.  It is hard to avoid mistakes in the subscripting,
which often runs slowly due to redundant internal calculations.</html:p>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                      <fr:author>
                        <fr:link href="/~avsm2/fcs/anil-madhavapeddy/" title="Anil Madhavapeddy" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/anil-madhavapeddy/" display-uri="anil-madhavapeddy" type="local">Anil Madhavapeddy</fr:link>
                      </fr:author>
                    </fr:authors>
                    <fr:uri>https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11-5/</fr:uri>
                    <fr:display-uri>focs-ex-11-5</fr:display-uri>
                    <fr:route>/~avsm2/fcs/focs-ex-11-5/</fr:route>
                    <fr:title text="Exercises › Matrix operations on arrays"><fr:link href="/~avsm2/fcs/focs-ex-11/" title="Exercises" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-ex-11/" display-uri="focs-ex-11" type="local">Exercises</fr:link> › Matrix operations on arrays</fr:title>
                    <fr:taxon>Exercise</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>Arrays of multiple dimensions are represented in OCaml by arrays of arrays. Write functions to
(a) create an <fr:tex display="inline"><![CDATA[n\times  n]]></fr:tex> identity matrix, given <fr:tex display="inline"><![CDATA[n]]></fr:tex>, and
(b) to <fr:link href="/~avsm2/fcs/focs-transpose/" title="Example: Matrix Transpose" uri="https://www.cl.cam.ac.uk/~avsm2/fcs/focs-transpose/" display-uri="focs-transpose" type="local">transpose</fr:link> an <fr:tex display="inline"><![CDATA[m\times  n]]></fr:tex> matrix. Identity matrices have the following form:</html:p>
                    <fr:tex display="block"><![CDATA[
\left ( {
\begin {array}{cccc}
   1 & 0 &  \cdots   & 0  \\
   0 & 1 &  \cdots   & 0  \\
    \vdots   &  \vdots   &  \ddots   &  \vdots    \\
   0 & 0 &  \cdots   & 1  \\
 \end {array}
 } \right )
]]></fr:tex>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Contributions">Contributions</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
  </fr:backmatter>
</fr:tree>
