Index: doc/papers/OOPSLA17/.gitignore
===================================================================
--- doc/papers/OOPSLA17/.gitignore	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/.gitignore	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,19 @@
+# generated by latex
+*.aux
+*.bbl
+*.blg
+*.brf
+*.dvi
+*.idx
+*.ilg
+*.ind
+*.log
+*.out
+*.pdf
+*.ps
+*.toc
+*.lof
+*.lot
+*.synctex.gz
+comment.cut
+timing.tex
Index: doc/papers/OOPSLA17/ACM-Reference-Format.bst
===================================================================
--- doc/papers/OOPSLA17/ACM-Reference-Format.bst	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/ACM-Reference-Format.bst	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,3412 @@
+%%% -*-BibTeX-*-
+%%% ====================================================================
+%%%  @BibTeX-style-file{
+%%%     author          = "Nelson H. F. Beebe, Boris Veytsman and Gerald Murray",
+%%%     version         = "1.18",
+%%%     date            = "10 July 2016",
+%%%     filename        = "ACM-Reference-Format.bst",
+%%%     email           = "beebe@math.utah.edu, beebe@acm.org,
+%%%                        beebe@computer.org, borisv@lk.net, murray@hq.acm.org", 
+%%%     codetable       = "ISO/ASCII",
+%%%     keywords        = "ACM Transactions bibliography style; BibTeX",
+%%%     license         = "public domain",
+%%%     supported       = "yes",
+%%%     abstract        = "",
+%%%  }
+%%% ====================================================================
+
+%  ACM BibTeX style, ACM-Reference-Format.bst
+%  for BibTeX version 0.99c, LaTeX version 3.141
+%  ACM extensions with code cleaned up, extended, and debugged 10--15-Nov-2008
+%  Revised 17-APRIL-2008 (Nelson)
+%  Revised 13-MARCH-2011 (Boris/Gerry)
+%  Revised 23-MARCH-2011 (Boris/Gerry)
+%  Revised 27-MARCH-2011 (Boris/Gerry)
+%  Revised 15-APRIL-2011 (Boris/Gerry)
+%  Revised 27-SEPTEMBER-2011 (Boris)
+%  Revised 10-JULY-2016 (Boris)
+%
+%
+% History (by Nelson)
+%
+% Based on 'acmtrans' (for ACM Journals)
+% Date: 28th April 2008
+%
+% 1. Avoid 'repeating' the 'month' values.
+% 2. Avoid incorrectly italicizing the volume number.
+% 3. Avoid non italicizing certain titles (book, inproceedings etc).
+% 4. NO series if there is NO volume.
+% 5. Sorting of reference with first surname.
+% 6. Article no added for Inproceedings.
+%
+% Date: 07th May 2008
+%
+% 1. Abbreviation list added
+%
+%   Citation format: [author-last-name year]
+%             [author-last-name and author-last-name year]
+%             [author-last-name, author-last-name, and author-last-name year]
+%             [author-last-name et al. year]
+%             [author-last-name]
+%             author-last-name [year]
+%             [author-last-name and author-last-name]
+%             [author-last-name et al.]
+%             [year] or [year,year]
+%             year or year,year
+%
+%   Reference list ordering: alphabetical by author or whatever passes
+%    for author in the absence of one.
+%
+% Features of the old acmtrans.bst:
+% =================================
+%
+% - all authors appear last name first.
+% - all pages are listed xx-xx, (no pp.) and are at the end of the reference
+% - publishers are identified as publisher, address
+% - conferences papers (inproceedings) may give city of conference,
+%   date of conference, and journal that the proceedings appear in.
+% - months abbreviated to max four letters (eg. Mar.)
+% - volume of a series indicated after the title of the series
+% - editors appear after edited title and are identified by a trailing "Eds."
+%   not in parentheses.  Editor names are not given in small caps.
+%   (unless there is no author line)
+% - names terminated with a period even if there is no first name.
+% - editions are indicated trailing after the work, not in parentheses.
+% - "et al." citations have a protected period to avoid bad spacing (jrh)
+% - "address" required when publisher given
+% - series (roman) and volume are in a sentence separate from (book-)title
+%
+%
+% Features of chicago.bst:
+% =======================
+%
+% - full names used in citations, but abbreviated citations are available
+%   (see above)
+% - if an entry has a "month", then the month and year are also printed
+%   as part of that bibitem.
+% - all conjunctions use "and" instead of "\&"
+% - major modification from Chicago Manual of Style (13th ed.) is that
+%   only the first author in a reference appears last name first-
+%   additional authors appear as J. Q. Public.
+% - pages are listed as "pp. xx-xx" in all entry types except
+%   article entries.
+% - book, inbook, and manual use "location: publisher" (or organization)
+%   for address and publisher. All other types list publishers separately.
+% - "pp." are used to identify page numbers for all entry types except
+%   articles.
+% - organization is used as a citation label if neither author nor editor
+%   is present (for manuals).
+% - "et al." is used for long author and editor lists, or when "others"
+%   is used.
+%
+% Modifications and bug fixes from newapa.bst:
+% ===========================================
+%
+%   - added month, year to bib entries if month is present
+%   - fixed bug with In proceedings, added necessary comma after title
+%   - all conjunctions changed to "and" from "\&"
+%   - fixed bug with author labels in my.full.label: "et al." now is
+%        generated when "others" is an author name
+%   - major modification from Chicago Manual of Style (13th ed.) is that
+%     only the first author in a reference appears last name first-
+%     additional authors appear as J. Q. Public.
+%   - pages are listed as "pp. xx-xx" in all entry types except
+%     article entries. Unnecessary (IMHO) "()" around page numbers
+%     were removed, and page numbers now don't end with a period.
+%   - created chicago.sty for use with this bibstyle (required).
+%   - fixed bugs in FUNCTION {format.vol.num.pages} for missing volume,
+%     number, and /or pages. Renamed to format.journal.volume.number.
+%   - fixed bug in formatting booktitles: additional period an error if
+%     book has a volume.
+%   - fixed bug: editors usually given redundant period before next clause
+%     (format.editors.dot) removed.
+%   - added label support for organizations, if both author and editor
+%     are missing (from alpha.bst). If organization is too long, then
+%     the key field is used for abbreviated citations.
+%   - In proceedings or books of several volumes, no comma was written
+%     between the "Volume x" and the page numbers (this was intentional
+%     in newapa.bst). Fixed.
+%   - Some journals may not have volumes/numbers, only month/year (eg.
+%     IEEE Computer). Fixed bug in article style that assumed volume/number
+%     was always present.
+%
+% Original documentation for newapa.sty:
+% =====================================
+%
+% This version was made by modifying the master file made by
+% Oren Patashnik (PATASHNIK@SCORE.STANFORD.EDU), and the 'named' BibTeX
+% style of Peter F. Patel-Schneider.
+%
+% Copyright (C) 1985, all rights reserved.
+% Copying of this file is authorized only if either
+% (1) you make absolutely no changes to your copy, including name, or
+% (2) if you do make changes, you name it something other than 'newapa.bst'.
+% There are undoubtably bugs in this style.  If you make bug fixes,
+% improvements, etc.  please let me know.  My e-mail address is:
+%    spencer@cgrg.ohio.state.edu or 71160.3141@compuserve.com
+%
+% This style was made from 'plain.bst', 'named.bst', and 'apalike.bst',
+% with lots of tweaking to make it look like APA style, along with tips
+% from Young Ryu and Brian Reiser's modifications of 'apalike.bst'.
+%
+%
+% Start of ACM-Reference-Format-Journals.bst
+%
+% Note: Many of the new bibentry 'fields' will only work with the 
+% 'ACM-Reference-Format-Journals.bst' file. Legacy .bib files (which will, in all probability,
+% NOT contain these new fields) will _still_ work with the ACM-Reference-Format-Journals.bst.
+% 
+%
+ENTRY
+  { address
+    advisor
+    archiveprefix
+    author
+    booktitle
+    chapter
+    city        % jtb: added
+    date        % jtb: added
+    edition
+    editor
+    eprint
+    howpublished
+    institution
+    journal
+    key
+    month
+    note
+    number
+    organization
+    pages
+    primaryclass
+    publisher
+    school
+    series
+    title
+    type
+    volume
+    year
+        % New keys recognized 
+        issue         % UTAH: used in, e.g., ACM SIGSAM Bulletin and ACM Communications in Computer Algebra
+        articleno
+        day           % UTAH: needed for newspapers, weeklies, bi-weeklies
+        doi           % UTAH
+        url           % UTAH
+        bookpages     % UTAH
+        numpages
+        lastaccessed  % UTAH: used only for @Misc{...}
+        coden         % UTAH
+        isbn          % UTAH
+        isbn-13       % UTAH
+        issn          % UTAH
+        lccn          % UTAH
+  }
+  {}
+  { label.year extra.label sort.year sort.label }
+
+INTEGERS { output.state before.all mid.sentence after.sentence after.block }
+
+INTEGERS { show-isbn-10-and-13 }  % initialized below in begin.bib
+
+INTEGERS { nameptr namesleft numnames }
+
+INTEGERS { multiresult }
+
+INTEGERS { len }
+
+INTEGERS { last.extra.num }
+
+STRINGS { s t t.org u }
+
+STRINGS { last.label next.extra }
+
+STRINGS { p1 p2 p3 page.count }
+
+FUNCTION { dump.stack.1 }
+{
+    duplicate$ "STACK[top] = [" swap$ * "]" * warning$
+}
+
+FUNCTION { dump.stack.2 }
+{
+    duplicate$ "STACK[top  ] = [" swap$ * "]" * warning$
+    swap$
+    duplicate$ "STACK[top-1] = [" swap$ * "]" * warning$
+    swap$
+}
+
+FUNCTION { empty.or.unknown }
+{
+  %% Examine the top stack entry, and push 1 if it is empty, or
+  %% consists only of whitespace, or is a string beginning with two
+  %% queries (??), and otherwise, push 0.
+  %%
+  %% This function provides a replacement for empty$, with the
+  %% convenient feature that unknown values marked by two leading
+  %% queries are treated the same as missing values, and thus, do not
+  %% appear in the output .bbl file, and yet, their presence in .bib
+  %% file(s) serves to mark values which are temporarily missing, but
+  %% are expected to be filled in eventually once more data is
+  %% obtained.  The TeX User Group and BibNet bibliography archives
+  %% make extensive use of this practice.
+  %%
+  %% An empty string cannot serve the same purpose, because just as in
+  %% statistics data processing, an unknown value is not the same as an
+  %% empty value.
+  %%
+  %% At entry: stack = ... top:[string]
+  %% At exit:  stack = ... top:[0 or 1]
+
+  duplicate$ empty$
+    { pop$ #1 }
+    { #1 #2 substring$ "??" = }
+  if$
+}
+
+FUNCTION { writeln }
+{
+  %% In BibTeX style files, the sequences
+  %%
+  %%     ... "one" "two" output
+  %%     ... "one" "two" output.xxx
+  %%
+  %% ship "one" to the output file, possibly following by punctuation,
+  %% leaving the stack with
+  %%
+  %%     ... "two"
+  %%
+  %% There is thus a one-string lag in output processing that must be
+  %% carefully handled to avoid duplicating a string in the output
+  %% file.  Unless otherwise noted, all output.xxx functions leave
+  %% just one new string on the stack, and that model should be born
+  %% in mind when reading or writing function code.
+  %%
+  %% BibTeX's asynchronous buffering of output from strings from the
+  %% stack is confusing because newline$ bypasses the buffer.  It
+  %% would have been so much easier for newline to be a character
+  %% rather than a state of the output-in-progress.
+  %%
+  %% The documentation in btxhak.dvi is WRONG:  it says
+  %%
+  %%    newline$ Writes onto the bbl file what's accumulated in the
+  %%             output buffer. It writes a blank line if and only
+  %%             if the output buffer is empty. Since write$ does
+  %%             reasonable line breaking, you should use this
+  %%             function only when you want a blank line or an
+  %%             explicit line break.
+  %%
+  %%    write$   Pops the top (string) literal and writes it on the
+  %%             output buffer (which will result in stuff being
+  %%             written onto the bbl file when the buffer fills
+  %%             up).
+  %%
+  %% Examination of the BibTeX source code shows that write$ does
+  %% indeed behave as claimed, but newline$ sends a newline character
+  %% directly to the output file, leaving the stack unchanged.  The
+  %% first line "Writes onto ... buffer." is therefore wrong.
+  %%
+  %% The original BibTeX style files almost always use "write$ newline$"
+  %% in that order, so it makes sense to hide that pair in a private
+  %% function like this one, named after a statement in Pascal,
+  %% the programming language embedded in the BibTeX Web program.
+
+  write$                % output top-of-stack string
+  newline$              % immediate write of newline (not via stack)
+}
+
+FUNCTION { init.state.consts }
+{
+  #0 'before.all :=
+  #1 'mid.sentence :=
+  #2 'after.sentence :=
+  #3 'after.block :=
+}
+
+FUNCTION { output.nonnull }
+{ % Stack in: ... R S T  Stack out: ... R T   File out: S<comma><space>
+  's :=
+  output.state mid.sentence =
+    {
+      ", " * write$
+    }
+    {
+      output.state after.block =
+        {
+          add.period$ writeln
+          "\newblock " write$
+        }
+        {
+          output.state before.all =
+            {
+              write$
+            }
+            {
+              add.period$ " " * write$
+            }
+          if$
+        }
+      if$
+      mid.sentence 'output.state :=
+    }
+  if$
+  s
+}
+
+FUNCTION { output.nonnull.dot.space }
+{ % Stack in: ... R S T  Stack out: ... R T   File out: S<dot><space>
+  's :=
+  output.state mid.sentence =           % { "<DEBUG output.nonnull.dot.space>. " * write$ }
+    {
+      ". " * write$
+    }
+    {
+      output.state after.block =
+        {
+          add.period$ writeln "\newblock " write$
+        }
+        {
+          output.state before.all =
+            {
+              write$
+            }
+            {
+              add.period$ " " * write$
+            }
+          if$
+        }
+      if$
+      mid.sentence 'output.state :=
+    }
+  if$
+  s
+}
+
+FUNCTION { output.nonnull.remove }
+{ % Stack in: ... R S T  Stack out: ... R T   File out: S<space>
+  's :=
+  output.state mid.sentence =
+    {
+      " " * write$
+    }
+    {
+      output.state after.block =
+        {
+          add.period$ writeln "\newblock " write$
+        }
+        {
+          output.state before.all =
+            {
+              write$
+            }
+            {
+              add.period$ " " * write$
+            }
+          if$
+        }
+      if$
+      mid.sentence 'output.state :=
+    }
+  if$
+  s
+}
+
+FUNCTION { output.nonnull.removenospace }
+{ % Stack in: ... R S T  Stack out: ... R T   File out: S
+  's :=
+  output.state mid.sentence =
+    {
+      "" * write$
+    }
+    {
+      output.state after.block =
+        {
+          add.period$ writeln "\newblock " write$
+        }
+        {
+          output.state before.all =
+            {
+              write$
+            }
+            {
+              add.period$ " " * write$
+            }
+          if$
+        }
+      if$
+      mid.sentence 'output.state :=
+    }
+  if$
+  s
+}
+
+FUNCTION { output }
+{ % discard top token if empty, else like output.nonnull
+  duplicate$ empty.or.unknown
+    'pop$
+    'output.nonnull
+  if$
+}
+
+FUNCTION { output.dot.space }
+{ % discard top token if empty, else like output.nonnull.dot.space
+  duplicate$ empty.or.unknown
+    'pop$
+    'output.nonnull.dot.space
+  if$
+}
+
+FUNCTION { output.removenospace }
+{ % discard top token if empty, else like output.nonnull.removenospace
+  duplicate$ empty.or.unknown
+    'pop$
+    'output.nonnull.removenospace
+  if$
+}
+
+FUNCTION { output.check }
+{ % like output, but warn if key name on top-of-stack is not set
+  't :=
+  duplicate$ empty.or.unknown
+    { pop$ "empty " t * " in " * cite$ * warning$ }
+    'output.nonnull
+  if$
+}
+
+FUNCTION { bibinfo.output.check }
+{ % like output.check, adding bibinfo field
+  't :=
+  duplicate$ empty.or.unknown
+    { pop$ "empty " t * " in " * cite$ * warning$ }
+    { "\bibinfo{" t "}{" * * swap$ * "}" *
+      output.nonnull }
+  if$
+}
+
+FUNCTION { output.check.dot.space }
+{ % like output.dot.space, but warn if key name on top-of-stack is not set
+  't :=
+  duplicate$ empty.or.unknown
+    { pop$ "empty " t * " in " * cite$ * warning$ }
+    'output.nonnull.dot.space
+  if$
+}
+
+FUNCTION { fin.block }
+{ % functionally, but not logically, identical to fin.entry
+   add.period$
+   writeln
+}
+
+FUNCTION { fin.entry }
+{
+   add.period$
+   writeln
+}
+
+FUNCTION { new.sentence }
+{ % update sentence state, with neither output nor stack change
+  output.state after.block =
+    'skip$
+    {
+      output.state before.all =
+        'skip$
+        { after.sentence 'output.state := }
+      if$
+    }
+  if$
+}
+
+FUNCTION { fin.sentence }
+{
+   add.period$
+   write$
+   new.sentence
+   ""
+}
+
+FUNCTION { new.block }
+{
+  output.state before.all =
+    'skip$
+    { after.block 'output.state := }
+  if$
+}
+
+FUNCTION { output.coden }       % UTAH
+{ % output non-empty CODEN as one-line sentence (stack untouched)
+  coden empty.or.unknown
+    { }
+    { "\showCODEN{" coden * "}" * writeln }
+  if$
+}
+
+FUNCTION { format.articleno }
+{
+  articleno empty.or.unknown
+     { "" }
+     {
+        numpages empty.or.unknown
+          { "articleno field, but no numpages field, in " cite$ * warning$ }
+          { }
+        if$
+        "Article \bibinfo{articleno}{" articleno * "}" *
+     }
+  if$
+}
+
+FUNCTION { format.year }
+{ % push year string or "????" onto output stack
+  %% Because year is a mandatory field, we always force SOMETHING
+  %% to be output
+  "\bibinfo{year}{" 
+  year empty.or.unknown
+    { "????" }
+    { year }
+  if$
+  *  "}" *
+}
+
+FUNCTION { format.day.month }
+{ % push "day month " or "month " or "" onto output stack
+  day empty.or.unknown
+    {
+      month empty.or.unknown
+        { "" }
+        { "\bibinfo{date}{" month * "} " *}
+      if$
+    }
+    {
+      month empty.or.unknown
+        { "" }
+        { "\bibinfo{date}{" day * " " * month * "} " *}
+      if$
+    }
+  if$
+}
+
+FUNCTION { format.day.month.year }     % UTAH
+{ % if month is empty, push "" else push "(MON.)" or "(DD MON.)"
+  % Needed for frequent periodicals: 2008. ... New York Times C-1, C-2, C-17 (23 Oct.)
+  % acm-*.bst addition: prefix parenthesized date string with
+  % ", Article nnn "
+  articleno empty.or.unknown
+    { "" }
+    { ", " format.articleno * }
+  if$
+  " (" * format.day.month * format.year * ")" *
+}
+
+FUNCTION { output.day.month.year }     % UTAH
+{ % if month is empty value, do nothing; else output stack top and
+  % leave with new top string "(MON.)" or "(DD MON.)"
+  % Needed for frequent periodicals: 2008. ... New York Times C-1, C-2, C-17 (23 Oct.)
+  format.day.month.year
+  output.nonnull.remove
+}
+
+FUNCTION { strip.doi } % UTAH
+{ % Strip any Web address prefix to recover the bare DOI, leaving the
+  % result on the output stack, as recommended by CrossRef DOI
+  % documentation.
+  % For example, reduce "http://doi.acm.org/10.1145/1534530.1534545" to
+  % "10.1145/1534530.1534545".  That is later typeset and displayed as
+  % doi:10.1145/1534530.1534545 as the LAST item in the reference list
+  % entry.  Publisher Web sites wrap this with a suitable link to a real
+  % URL to resolve the DOI, and the master http://dx.doi.org/ address is
+  % preferred, since publisher-specific URLs can disappear in response
+  % to economic events.  All journals are encouraged by the DOI
+  % authorities to use that typeset format and link procedures for
+  % uniformity across all publications that include DOIs in reference
+  % lists.
+  % The numeric prefix is guaranteed to start with "10.", so we use
+  % that as a test.
+  doi #1 #3 substring$ "10." =
+    { doi }
+    {
+      doi #1 #7 substring$ "http://" =
+        {
+            doi #8 doi text.length$ #7 - substring$ 't := % get modifiable copy of rest of DOI
+
+            "INTERNAL STYLE-FILE ERROR" 's :=
+
+            % search for next "/" and assign its suffix to s
+
+            { t text.length$ }
+            {
+              t #1 #1 substring$ "/" =
+                {
+                  % save rest of string as true DOI (should be 10.xxxx/yyyy)
+                  t #2 t text.length$ #1 - substring$ 's :=
+                  "" 't :=    % empty string t terminates the loop
+                }
+                {
+                  % discard first character and continue loop: t <= substring(t,2,last)
+                  t #2 t text.length$ #1 - substring$ 't :=
+                }
+              if$
+            }
+            while$
+
+            % check for valid DOI (should be 10.xxxx/yyyy)
+            s #1 #3 substring$ "10." =
+              { }
+              { "unrecognized DOI substring " s * " in DOI value [" * doi * "]" * warning$ }
+            if$
+
+            s   % push the stripped DOI on the output stack
+
+        }
+        {
+          "unrecognized DOI value [" doi * "]" * warning$
+          doi   % push the unrecognized original DOI on the output stack
+        }
+      if$
+    }
+  if$
+}
+
+%
+% Change by BV: added standard prefix to URL
+%
+FUNCTION { output.doi } % UTAH
+{ % output non-empty DOI as one-line sentence (stack untouched)
+  doi empty.or.unknown
+    { }
+    {
+      %% NB: We want URLs at beginning of line to reduce likelihood of
+      %% BibTeX's nasty line wrapping after column 79, which then requires
+      %% manual (or automated) editing of the .bbl file to repair.
+      %% The \url{} macro strips percent-newlines, and is thus safe in
+      %% the presence of the line wrapping, but \path|...| and
+      %% \verb|...| do not.
+      "\showDOI{%" writeln
+      "\url{http://dx.doi.org/" strip.doi * "}}" * writeln
+    }
+  if$
+}
+
+FUNCTION { output.isbn }                % UTAH
+{ % output non-empty ISBN-10 and/or ISBN-13 as one-line sentences (stack untouched)
+  show-isbn-10-and-13
+    {
+      %% show both 10- and 13-digit ISBNs
+      isbn empty.or.unknown
+        { }
+        {
+          "\showISBNx{" isbn * "}" * writeln
+        }
+      if$
+      isbn-13 empty.or.unknown
+        { }
+        {
+          "\showISBNxiii{" isbn-13 * "}" * writeln
+        }
+      if$
+    }
+    {
+      %% show 10-digit ISBNs only if 13-digit ISBNs not available
+      isbn-13 empty.or.unknown
+        {
+          isbn empty.or.unknown
+            { }
+            {
+              "\showISBNx{" isbn * "}" * writeln
+            }
+          if$
+        }
+        {
+          "\showISBNxiii{" isbn-13 * "}" * writeln
+        }
+      if$
+    }
+  if$
+}
+
+FUNCTION { output.issn } % UTAH
+{ % output non-empty ISSN as one-line sentence (stack untouched)
+  issn empty.or.unknown
+    { }
+    { "\showISSN{" issn * "}" * writeln }
+  if$
+}
+
+FUNCTION { output.issue }
+{ % output non-empty issue number as a one-line sentence (stack untouched)
+  issue empty.or.unknown
+    { }
+    { "Issue " issue * "." * writeln }
+  if$
+}
+
+FUNCTION { output.lccn } % UTAH
+{ % return with stack untouched
+  lccn empty.or.unknown
+    { }
+    { "\showLCCN{" lccn * "}" * writeln }
+  if$
+}
+
+FUNCTION { output.note } % UTAH
+{ % return with stack empty
+  note empty.or.unknown
+    { }
+    { "\shownote{" note add.period$ * "}" * writeln }
+  if$
+}
+
+FUNCTION { output.note.check } % UTAH
+{ % return with stack empty
+  note empty.or.unknown
+    { "empty note in " cite$ * warning$ }
+    { "\shownote{" note add.period$ * "}" * writeln }
+  if$
+}
+
+FUNCTION { output.eprint } % 
+{ % return with stack empty
+  eprint empty.or.unknown
+    { }
+    { "\showeprint" 
+         archiveprefix empty.or.unknown
+           { }
+           { "["  archiveprefix "l" change.case$ "]" * * * }
+         if$
+         "{" *
+         primaryclass empty.or.unknown 
+           { }
+           { primaryclass "/" * *}
+         if$
+         eprint "}" * *    
+         writeln
+    }
+  if$
+}
+
+
+%
+% Changes by BV 2011/04/15.  Do not output
+% url if doi is defined
+%
+FUNCTION { output.url } % UTAH
+{ % return with stack untouched
+  % output URL and associated lastaccessed fields
+  doi empty.or.unknown
+  {
+    url empty.or.unknown
+      { }
+      {
+          %% NB: We want URLs at beginning of line to reduce likelihood of
+          %% BibTeX's nasty line wrapping after column 79, which would require
+          %% manual (or automated) editing of the .bbl file to repair.  However,
+          %% the \url{} macro handles the unwrapping job automatically.
+          "\showURL{%" writeln
+          lastaccessed empty.or.unknown
+            { "" }
+            { "Retrieved " lastaccessed * " from " * }
+          if$
+
+          %% The URL field may contain a semicolon-separated list of Web
+          %% addresses, and we locate and wrap each of them in \url{...}.
+          %% The simplistic approach of putting the entire list into the
+          %% macro argument is that the semicolons are typeset in a
+          %% typewriter font, and no space follows them.
+          %%
+          %% We therefore replace the original code
+          %%    "\url{" * url * "}}" * writeln
+          %% with this character-at-a-time loop:
+
+          "\url{" *
+
+          url 't :=                       % get modifiable copy of URL list
+
+          { t text.length$ }
+          {
+            t #1 #1 substring$ ";" =
+              {                         % then split argument at separator
+                "};" * writeln
+                "\url{"
+              }
+              {                         % else concatenate nonblank character to argument
+                t #1 #1 substring$ " " =
+                  { }
+                  { t #1 #1 substring$ * }
+                if$
+              }
+            if$
+
+            t #2 t text.length$ #1 - substring$ 't :=
+          }
+          while$
+
+          "}}" * writeln
+      }
+    if$
+  }
+  { }
+  if$
+}
+
+FUNCTION { output.year.check }
+{ % warn if year empty, else output top string and leave " YEAR<label>" on stack in mid-sentence
+  year empty.or.unknown
+     { "empty year in " cite$ * warning$ }
+     { write$
+        " \bibinfo{year}{" year * "}"  *
+	"\natexlab{" extra.label * "}" * *
+       mid.sentence 'output.state :=
+     }
+  if$
+}
+
+FUNCTION { not }
+{
+    { #0 }
+    { #1 }
+  if$
+}
+
+FUNCTION { and }
+{
+    'skip$
+    { pop$ #0 }
+  if$
+}
+
+FUNCTION { or }
+{
+   { pop$ #1 }
+    'skip$
+  if$
+}
+
+FUNCTION { le }
+{
+  %% test whether first number is less than or equal to second number
+  %% stack in:  n1 n2
+  %% stack out: if n1 <= n2 then 1 else 0
+
+  %% "DEBUG: le " cite$ * warning$
+  > { #0 } { #1 } if$
+}
+
+FUNCTION { ge }
+{
+  %% test whether first number is greater than or equal to second number
+  %% stack in:  n1 n2
+  %% stack out: if n1 >= n2 then 1 else 0
+
+  %% "DEBUG: ge " cite$ * warning$
+  < { #0 } { #1 } if$
+}
+
+FUNCTION { is.leading.digit }
+{
+  %% test whether first character of string is a digit
+  %% stack in:  string
+  %% stack out: if first-char-is-digit then 1 else 0
+
+  #1 #1 substring$                      % replace string by string[1:1]
+  duplicate$                            % string[1:1] string[1:1]
+  chr.to.int$
+  "0" chr.to.int$ swap$ le              % "0" <= string[1:1] --> 0-or-1
+  swap$                                 % 0-or-1 string[1:1]
+  chr.to.int$
+  "9" chr.to.int$ le                    % string[1:1} <= "9" --> 0-or-1
+  and
+}
+
+FUNCTION { skip.digits }
+{
+  %% skip over leading digits in string
+  %% stack in:  string
+  %% stack out: rest-of-string leading-digits
+
+  %% "DEBUG: enter skip.digits " cite$ * warning$
+
+  %% dump.stack.1
+
+  duplicate$
+  't :=
+  't.org :=
+  "" 'u :=
+
+  { t text.length$ }
+  {
+    %% "=================DEBUG: skip.digits   t = [" t * "]" * warning$
+    t is.leading.digit
+      { t #2 t text.length$ #1 - substring$ }
+      {
+        t 'u :=
+        ""
+      }
+    if$
+    't :=
+  }
+  while$
+
+  u                                                             % rest of string
+  t.org #1 t.org text.length$ u text.length$ - substring$       % leading digits
+
+  %% "DEBUG: t.org = [" t.org * "]" * warning$
+  %% "DEBUG: u     = [" u * "]" * warning$
+
+  %% dump.stack.2
+
+  %% "DEBUG: leave skip.digits " cite$ * warning$
+}
+
+FUNCTION { skip.nondigits }
+{
+  %% skip over leading nondigits in string
+  %% stack in:  string
+  %% stack out: rest-of-string
+
+  %% "DEBUG: enter skip.nondigits " cite$ * warning$
+
+  't :=
+  "" 'u :=
+
+  { t text.length$ }
+  {
+    %% "=================DEBUG: skip.nondigits   t = [" t * "]" * warning$
+    t is.leading.digit
+      {
+        t 'u :=
+        ""
+      }
+      { t #2 t text.length$ #1 - substring$ }
+    if$
+    't :=
+  }
+  while$
+
+  u                     % rest of string
+
+  %% dump.stack.1
+  %% "DEBUG: leave skip.nondigits " cite$ * warning$
+}
+
+FUNCTION { parse.next.number }
+{
+  %% stack in:  string
+  %% stack out: rest-of-string next-numeric-part-of-string
+  %% Example:
+  %% stack in:  "123:1--123:59"
+  %% stack out: ":1--123:59" "123"
+
+  's :=
+  s skip.nondigits 's :=
+  s skip.digits
+}
+
+FUNCTION { reduce.pages.to.page.count }
+{
+  %% Stack in:  arbitrary-and-unused
+  %% Stack out: unchanged
+  %%
+  %% For the new-style pagination with article number and numpages or
+  %% pages, we expect to have BibTeX entries containing something like
+  %%     articleno = "17",
+  %%     pages     = "1--23",
+  %% with output "Article 17, 23 pages",
+  %% or
+  %%     articleno = "17",
+  %%     numpages  = "23",
+  %% with output "Article 17, 23 pages",
+  %% or
+  %%     articleno = "17",
+  %%     pages     = "17:1--17:23",
+  %% with output "Article 17, 23 pages",
+  %%
+  %% If articleno is missing or empty, then we should output "1--23",
+  %% "23" (with a warning of a missing articleno), or "17:1--17:23",
+  %% respectively.
+
+  %% "DEBUG: enter reduce.pages.to.page.count " cite$ * warning$
+
+  %% "DEBUG: pages = [" pages * "]" * warning$
+
+  pages
+  parse.next.number 'p1 :=
+  parse.next.number 'p2 :=
+  parse.next.number 'p3 :=
+  parse.next.number 'page.count :=
+
+  duplicate$
+  empty.or.unknown
+    {  }
+    {
+      duplicate$ "unexpected trailing garbage [" swap$ *
+      "] after n:p1--n:p2 in pages = [" *
+      pages *
+      "] in " *
+      cite$ *
+      warning$
+    }
+  if$
+
+  pop$
+
+  %% "DEBUG: reduce.pages.to.page.count: "
+  %% " p1 = " p1 * *
+  %% " p2 = " p2 * *
+  %% " p3 = " p3 * *
+  %% " p4 = " page.count * *
+  %% " in " cite$ * * warning$
+
+  p1 p3 =   p2 "1" =   and   numpages empty.or.unknown   and
+    { "INFO: reduced pages = [" pages * "] to numpages = [" * page.count * "]" * warning$ }
+    {
+      numpages empty.or.unknown
+        { pages }
+        { numpages }
+      if$
+      'page.count :=
+    }
+  if$
+
+  p1 "1" =   p3 empty.or.unknown   and   numpages empty.or.unknown   and
+    {
+      p2 'page.count :=
+      "INFO: reduced pages = [" pages * "] to numpages = [" * page.count * "]" * warning$
+    }
+    {
+      numpages empty.or.unknown
+        { pages }
+        { numpages }
+      if$
+      'page.count :=
+    }
+  if$
+
+  %% "DEBUG: leave reduce.pages.to.page.count " cite$ * warning$
+}
+
+FUNCTION { new.block.checkb }
+{ % issue a new.block only if at least one of top two stack strings is not empty
+  empty.or.unknown
+  swap$ empty.or.unknown
+  and
+    'skip$
+    'new.block
+  if$
+}
+
+FUNCTION { field.or.null }
+{ % convert empty value to null string, else return value
+  duplicate$ empty.or.unknown
+    { pop$ "" }
+    'skip$
+  if$
+}
+
+FUNCTION { emphasize }
+{ % emphasize a non-empty top string on the stack (WITHOUT italic correction)
+  duplicate$ empty.or.unknown
+    { pop$ "" }
+    { "{\em " swap$ * "}" * }
+  if$
+}
+
+FUNCTION { emphasize.with.italic.correction }
+{ % convert empty string to null string, or emphasize with a trailing italic correction
+  duplicate$ empty.or.unknown
+    { pop$ "" }
+    { "{\em " swap$ * "\/}" * }
+  if$
+}
+
+FUNCTION { comma }
+{ % convert empty string to null string, or brace string and add trailing comma
+  duplicate$ empty.or.unknown
+    { pop$ "" }
+    { "{" swap$ * "}," * }
+  if$
+}
+
+FUNCTION { format.names }
+{
+  % Format bibliographical entries with the first author last name first,
+  % and subsequent authors with initials followed by last name.
+  % All names are formatted in this routine.
+
+  's :=
+  #1 'nameptr :=               % nameptr = 1;
+  s num.names$ 'numnames :=    % numnames = num.name$(s);
+  numnames 'namesleft :=
+    { namesleft #0 > }
+    { nameptr #1 =
+        %NO: BAD ORDER: {"{" s nameptr "{ff~}{ll}{, jj}{, vv}" format.name$ * "}" * 't := }
+        %NO: BAD ORDER: {"{" s nameptr "{ff~}{ll}{, jj}{, vv}" format.name$ * "}" * 't := }
+        {"\bibinfo{person}{" s nameptr "{ff }{vv }{ll}{, jj}" format.name$ * "}" * 't := }
+        {"\bibinfo{person}{" s nameptr "{ff }{vv }{ll}{, jj}" format.name$ * "}" * 't := }
+      if$
+      nameptr #1 >
+        {
+          namesleft #1 >
+            { ", " * t * }
+            {
+              numnames #2 >
+                { "," * }
+                'skip$
+              if$
+              t "{\sc others}" =
+                { " {et~al\mbox{.}}" * } % jrh: avoid spacing problems
+                { " {and} " * t * } % from Chicago Manual of Style
+              if$
+            }
+          if$
+        }
+        't
+      if$
+      nameptr #1 + 'nameptr :=          % nameptr += 1;
+      namesleft #1 - 'namesleft :=      % namesleft =- 1;
+    }
+  while$
+}
+
+FUNCTION { my.full.label }
+{
+  's :=
+  #1 'nameptr :=               % nameptr = 1;
+  s num.names$ 'numnames :=    % numnames = num.name$(s);
+  numnames 'namesleft :=
+    { namesleft #0 > }
+
+    { s nameptr "{vv~}{ll}" format.name$ 't :=  % get the next name
+      nameptr #1 >
+        {
+          namesleft #1 >
+            { ", " * t * }
+            {
+              numnames #2 >
+                { "," * }
+                'skip$
+              if$
+              t "others" =
+                { " et~al\mbox{.}" * } % jrh: avoid spacing problems
+                { " and " * t * } % from Chicago Manual of Style
+              if$
+            }
+          if$
+        }
+        't
+      if$
+      nameptr #1 + 'nameptr :=          % nameptr += 1;
+      namesleft #1 - 'namesleft :=      % namesleft =- 1;
+    }
+  while$
+
+}
+
+FUNCTION { format.names.fml }
+{
+  % Format names in "familiar" format, with first initial followed by
+  % last name. Like format.names, ALL names are formatted.
+  % jtb: The names are NOT put in small caps
+
+  's :=
+  #1 'nameptr :=               % nameptr = 1;
+  s num.names$ 'numnames :=    % numnames = num.name$(s);
+  numnames 'namesleft :=
+    { namesleft #0 > }
+
+    {
+      "\bibinfo{person}{" s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ * "}" * 't :=
+
+      nameptr #1 >
+        {
+          namesleft #1 >
+            { ", " * t * }
+            {
+              numnames #2 >
+                { "," * }
+                'skip$
+              if$
+              t "{others}" =
+                { " {et~al\mbox{.}}" * }
+                { " {and} " * t * }
+              if$
+            }
+          if$
+        }
+        't
+      if$
+      nameptr #1 + 'nameptr :=          % nameptr += 1;
+      namesleft #1 - 'namesleft :=      % namesleft =- 1;
+    }
+  while$
+}
+
+FUNCTION { format.authors }
+{
+  author empty.or.unknown
+    { "" }
+    { 
+      "\bibfield{author}{" 
+      author format.names add.period$ * "}" *} % jtb: add period if none before
+  if$
+}
+
+FUNCTION { format.key }
+{
+  empty.or.unknown
+    { key field.or.null }
+    { "" }
+  if$
+}
+
+FUNCTION { format.no.key }
+{
+  empty.or.unknown
+    { "" }
+    { "" }
+  if$
+}
+
+FUNCTION { format.editors.fml }
+{
+  % Format editor names for use in the "in" types: inbook, incollection,
+  % inproceedings: first initial, then last names. When editors are the
+  % LABEL for an entry, then format.editor is used which lists editors
+  % by last name first.
+
+  editor empty.or.unknown
+    { "" }
+    {
+      "\bibfield{editor}{" 
+      editor format.names.fml 
+      *  "}" *
+      editor num.names$ #1 >
+        { " (Eds.)" * }
+        { " (Ed.)" * }
+      if$
+    }
+  if$
+}
+
+FUNCTION { format.editors }
+{ % format editor names for use in labels, last names first.
+  editor empty.or.unknown
+    { "" }
+    {
+      "\bibfield{editor}{" 
+      editor format.names
+      *  "}" *
+      editor num.names$ #1 >
+        { " (Eds.)." * }
+        { " (Ed.)." * }
+      if$
+    }
+  if$
+}
+
+FUNCTION { format.articletitle }
+{
+  title empty.or.unknown
+    { "" }
+    % Use this to preserve lettercase in titles:
+    { "\showarticletitle{" title * "}" * }
+    % Use this for downcase title style:
+    % { \showarticletitle{" title "t" change.case$ * "}" * }
+  if$
+}
+
+FUNCTION { format.title }
+{
+  title empty.or.unknown
+    { "" }
+    % Use this to preserve lettercase in titles:
+    { "\bibinfo{title}{" title * "}" * }
+    % Use this for downcase title style:
+    % { title "t" change.case$ }
+  if$
+}
+
+FUNCTION { n.dashify }
+{
+  't :=
+  ""
+    { t empty.or.unknown not }
+    {
+      t #1 #1 substring$ "-" =
+        {
+          t #1 #2 substring$ "--" = not
+            { "--" *
+              t #2 global.max$ substring$ 't :=
+            }
+            {
+              { t #1 #1 substring$ "-" = }
+              {
+                "-" *
+                t #2 global.max$ substring$ 't :=
+              }
+              while$
+            }
+          if$
+        }
+        {
+          t #1 #1 substring$ *
+          t #2 global.max$ substring$ 't :=
+        }
+      if$
+    }
+  while$
+}
+
+FUNCTION { format.btitle }
+{
+  "\bibinfo{booktitle}{"
+  edition empty.or.unknown
+  { title emphasize }
+  { title empty.or.unknown
+    { title emphasize } % jtb: what is this supposed to do ?!?
+    { "{\em " title * "\/} (\bibinfo{edition}{" * edition "l" change.case$ *
+    "} ed.)" * } % jtb: no parens for ed.
+    if$
+  }
+  if$
+  * "}" *
+}
+
+FUNCTION { format.emphasize.booktitle }
+{ % push "" or "{\em booktitle}" or "{\em booktitle}, (second ed.)" on stack
+  "\bibinfo{booktitle}{"
+  edition empty.or.unknown
+    { booktitle emphasize }
+    { booktitle empty.or.unknown
+      { "" }
+      { "{\em " booktitle * "} (\bibinfo{edition}{" *
+      edition "l" change.case$ * "} ed.)" * }
+      if$
+    }
+  if$
+  * "}" *
+}
+
+FUNCTION { format.city }
+{
+  % jtb: if the preceding string (the title of the conference) is non-empty,
+  % jtb: append the location, otherwise leave empty (so as to trigger the
+  % jtb: error message in output.check
+
+  duplicate$ empty.or.unknown
+    { }
+    {
+      city empty.or.unknown
+        {
+          date empty.or.unknown
+            { }
+            { " (" * date * ")" * }
+          if$
+        }
+        {
+          date empty.or.unknown
+            { " (" * city * ")" * }
+            { " (" * city * ", " * date * ")" * }
+          if$
+        }
+      if$
+    }
+  if$
+}
+
+FUNCTION { tie.or.space.connect }
+{
+  duplicate$ text.length$ #3 <
+    { "~" }
+    { " " }
+  if$
+  swap$ * *
+}
+
+FUNCTION { either.or.check }
+{
+  empty.or.unknown
+    'pop$
+    { "can't use both " swap$ * " fields in " * cite$ * warning$ }
+  if$
+}
+
+FUNCTION { format.bvolume }
+{
+  % jtb: If there is a series, this is added and the volume trails after it.
+  % jtb: Otherwise, "Vol" is Capitalized.
+
+  volume empty.or.unknown
+    { "" }
+    {
+      series empty.or.unknown
+        { "Vol.~\bibinfo{volume}{" volume "}" * *}
+        { "\bibinfo{series}{" series "}, " * *
+          "Vol.~\bibinfo{volume}{" volume "}" * * *}
+      if$
+      "volume and number" number either.or.check
+    }
+  if$
+}
+
+FUNCTION { format.bvolume.noseries }
+{
+  volume empty.or.unknown
+    { "" }
+    { "Vol.~\bibinfo{volume}{" volume "}" * *
+      "volume and number" number either.or.check
+    }
+  if$
+}
+
+FUNCTION { format.series }
+{
+  series empty.or.unknown
+    {""}
+    {" {\em (\bibinfo{series}{" * series "})}" *}
+  if$
+}
+
+FUNCTION { format.number.series }
+{
+  volume empty.or.unknown
+    {
+      number empty.or.unknown
+        {
+          volume empty.or.unknown
+          { "" }
+          {
+            series empty.or.unknown
+              { "" }
+              { " (\bibinfo{series}{" series * "})" * }
+            if$
+          }
+          if$
+        }                                       %    { series field.or.null }
+        {
+          output.state mid.sentence =
+            { "Number" }                        % gnp - changed to mixed case always
+            { "Number" }
+          if$
+          number tie.or.space.connect series empty.or.unknown
+            { "there's a number but no series in " cite$ * warning$ }
+            { " in \bibinfo{series}{" * series * "}" * }
+          if$
+        }
+      if$
+    }
+    {
+      ""
+    }
+  if$
+}
+
+FUNCTION { multi.page.check }
+{
+  't :=
+  #0 'multiresult :=
+    { multiresult not
+      t empty.or.unknown not
+      and
+    }
+    { t #1 #1 substring$
+      duplicate$ "-" =
+      swap$ duplicate$ "," =
+      swap$ "+" =
+      or or
+    { #1 'multiresult := }
+    { t #2 global.max$ substring$ 't := }
+      if$
+    }
+  while$
+  multiresult
+}
+
+FUNCTION { format.pages }
+{
+  pages empty.or.unknown
+    { "" }
+    { "\bibinfo{pages}{"
+      pages multi.page.check
+        { pages n.dashify } % gnp - removed () % jtb: removed pp.
+        { pages }
+      if$
+      * "}" *
+    }
+  if$
+}
+
+FUNCTION { format.pages.check.without.articleno }
+{ %% format pages field only if articleno is absent
+  %% Stack out: pages-specification
+  numpages missing$ pages missing$ and
+    { "page numbers missing in both pages and numpages fields in " cite$ * warning$ }
+    { }
+  if$
+
+  articleno empty.or.unknown
+    {
+      pages missing$
+        { numpages }
+        { format.pages }
+      if$
+    }
+    { "" }
+  if$
+}
+
+FUNCTION { format.pages.check }
+{
+  pages empty.or.unknown
+    { "page numbers missing in " cite$ * warning$ "" }
+    { pages n.dashify }
+  if$
+}
+
+FUNCTION { format.bookpages }
+{
+  bookpages empty.or.unknown
+    { "" }
+    { bookpages "book pages" tie.or.space.connect }
+  if$
+}
+
+FUNCTION { format.named.pages }
+{
+  pages empty.or.unknown
+    { "" }
+    { format.pages "pages" tie.or.space.connect }
+  if$
+}
+
+%
+% Changed by Boris Veytsman, 2011-03-13
+% Now the word "pages" is printed even if
+% there field pages is not empty.
+%
+
+FUNCTION { format.page.count }
+{
+  page.count empty.or.unknown
+    { "" }
+    {
+      articleno empty.or.unknown
+        { "numpages field, but no articleno field, in " cite$ * warning$ }
+        { }
+      if$
+      "\bibinfo{numpages}{" page.count * "}~pages" *
+    }
+  if$
+}
+
+FUNCTION { format.articleno.numpages }
+{
+  %% There are seven possible outputs, depending on which fields are set.
+  %%
+  %% These four are handled here:
+  %%
+  %%     articleno, numpages, pages     -> "Article articleno-value, numpages-value pages"
+  %%     articleno, numpages            -> "Article articleno-value, numpages-value pages"
+  %%     articleno, pages               -> "Article articleno-value, reduced-pages-value pages"
+  %%     articleno                      -> "Article articleno-value" and warn about missing numpages
+  %%
+  %% The remaining three have already been handled by
+  %% format.pages.check.without.articleno:
+  %%
+  %%     numpages, pages                -> "pages-value"
+  %%     numpages                       -> "numpages-value"
+  %%     pages                          -> "pages-value"
+
+  articleno empty.or.unknown
+    {
+      numpages empty.or.unknown
+        { }
+        { "require articleno with numpages field in " cite$ * warning$ }
+      if$
+      ""
+    }
+    {
+      numpages empty.or.unknown
+        {
+          pages empty.or.unknown
+            {
+              "require pages or numpages fields with articleno field in " cite$ * warning$
+              "" 'page.count :=
+            }
+            { reduce.pages.to.page.count }
+          if$
+        }
+        { numpages 'page.count := }
+      if$
+
+      %% The Article number is now handled in format.day.month.year because
+      %% ACM prefers the style "Digital Libraries 12, 3, Article 5 (July 2008)"
+      %% over "Digital Libraries 12, 3 (July 2008), Article 5"
+      %% format.articleno output
+      format.page.count
+    }
+  if$
+}
+
+FUNCTION { format.journal.volume.number.day.month.year }
+{
+  % By Young (and Spencer)
+  % GNP - fixed bugs with missing volume, number, and/or pages
+  %
+  % Format journal, volume, number, pages for article types.
+  %
+  journal empty.or.unknown
+    { "no journal in " cite$ * warning$
+      "" }
+%    { journal emphasize.with.italic.correction }
+     {
+       "\bibinfo{journal}{"
+           journal "Journal of the ACM" =
+       { "{\it J. ACM}" }
+       {
+           journal "American Mathematical Society Translations" =
+       { "{\it Amer. Math. Soc. Transl.}" }
+       {
+           journal "Bulletin of the American Mathematical Society" =
+       { "{\it Bull. Amer. Math. Soc.}" }
+       {
+           journal "Proceedings of the American Mathematical Society" =
+       { "{\it Proc. Amer. Math. Soc.}" }
+       {
+           journal "Transactions of the American Mathematical Society" =
+       { "{\it Trans. Amer. Math. Soc.}" }
+       {
+           journal "Communications of the {ACM}" =
+       { "{\it Commun. {ACM}}" }
+       {
+           journal "{ACM} Computing Surveys" =
+       { "{\it Comput. Surveys}" }
+       {
+           journal "{ACM} Transactions on Mathematical Software" =
+       { "{\it {ACM} Trans. Math. Software}" }
+       {
+           journal "{ACM} {SIGNUM} Newsletter" =
+       { "{\it {ACM} {SIGNUM} Newslett.}" }
+       {
+           journal "American Journal of Sociology" =
+       { "{\it Amer. J. Sociology}" }
+       {
+           journal "Journal of the American Statistical Association" =
+       { "{\it J. Amer. Statist. Assoc.}" }
+       {
+           journal "Applied Mathematics and Computation" =
+       { "{\it Appl. Math. Comput.}" }
+       {
+           journal "American Mathematical Monthly" =
+       { "{\it Amer. Math. Monthly}" }
+       {
+           journal "British Journal of Mathematical and Statistical Psychology" =
+       { "{\it Brit. J. Math. Statist. Psych.}" }
+       {
+           journal "Canadian Mathematical Bulletin" =
+       { "{\it Canad. Math. Bull.}" }
+       {
+           journal "Journal of Computational and Applied Mathematics" =
+       { "{\it J. Comput. Appl. Math.}" }
+       {
+           journal "Journal of Computational Physics" =
+       { "{\it J. Comput. Phys.}" }
+       {
+           journal "Computers and Structures" =
+       { "{\it Comput. \& Structures}" }
+       {
+           journal "The Computer Journal" =
+       { "{\it Comput. J.}" }
+       {
+           journal "Journal of Computer and System Sciences" =
+       { "{\it J. Comput. System Sci.}" }
+       {
+           journal "Contemporary Mathematics" =
+       { "{\it Contemp. Math.}" }
+       {
+           journal "Crelle's Journal" =
+       { "{\it Crelle's J.}" }
+       {
+           journal "Giornale di Mathematiche" =
+       { "{\it Giorn. Mat.}" }
+       {
+           journal "{IEEE} Transactions on Computers" =
+       { "{\it {IEEE} Trans. Comput.}" }
+       {
+           journal "{IEEE} Transactions on Automatic Control" =
+       { "{\it {IEEE} Trans. Automat. Control}" }
+       {
+           journal "Proceedings of the {IEEE}" =
+       { "{\it Proc. {IEEE}}" }
+       {
+           journal "{IEEE} Transactions on Aerospace and Electronic Systems" =
+       { "{\it {IEEE} Trans. Aerospace Electron. Systems}" }
+       {
+           journal "{IMA} Journal of Numerical Analysis" =
+       { "{\it {IMA} J. Numer. Anal.}" }
+       {
+           journal "Information Processing Letters" =
+       { "{\it Inform. Process. Lett.}" }
+       {
+           journal "Journal of the Institute of Mathematics and its Applications" =
+       { "{\it J. Inst. Math. Appl.}" }
+       {
+           journal "International Journal of Control" =
+       { "{\it Internat. J. Control}" }
+       {
+           journal "International Journal for Numerical Methods in Engineering" =
+       { "{\it Internat. J. Numer. Methods Engrg.}" }
+       {
+           journal "International Journal of Supercomputing Applications" =
+       { "{\it Internat. J. Supercomputing Applic.}" }
+       {
+           journal "Journal of Research of the National Bureau of Standards" =
+       { "{\it J. Res. Nat. Bur. Standards}" }
+       {
+           journal "Linear Algebra and its Applications" =
+       { "{\it Linear Algebra Appl.}" }
+       {
+           journal "Journal of Mathematical Analysis and Applications" =
+       { "{\it J. Math. Anal. Appl.}" }
+       {
+           journal "Mathematische Annalen" =
+       { "{\it Math. Ann.}" }
+       {
+           journal "Journal of Mathematical Physics" =
+       { "{\it J. Math. Phys.}" }
+       {
+           journal "Mathematics of Computation" =
+       { "{\it Math. Comp.}" }
+       {
+           journal "Mathematica Scandinavica" =
+       { "{\it Math. Scand.}" }
+       {
+           journal "Mathematical Tables and Other Aids to Computation" =
+       { "{\it Math. Tables Aids Comput.}" }
+       {
+           journal "Numerische Mathematik" =
+       { "{\it Numer. Math.}" }
+       {
+           journal "Pacific Journal of Mathematics" =
+       { "{\it Pacific J. Math.}" }
+       {
+           journal "Journal of Parallel and Distributed Computing" =
+       { "{\it J. Parallel and Distrib. Comput.}" }
+       {
+           journal "Parallel Computing" =
+       { "{\it Parallel Comput.}" }
+       {
+           journal "Philosophical Magazine" =
+       { "{\it Philos. Mag.}" }
+       {
+           journal "Proceedings of the National Academy of Sciences of the USA" =
+       { "{\it Proc. Nat. Acad. Sci. U. S. A.}" }
+       {
+           journal "Quarterly Journal of Mathematics, Oxford, Series (2)" =
+       { "{\it Quart. J. Math. Oxford Ser. (2)}" }
+       {
+           journal "Quarterly of Applied Mathematics" =
+       { "{\it Quart. Appl. Math.}" }
+       {
+           journal "Review of the International Statisical Institute" =
+       { "{\it Rev. Inst. Internat. Statist.}" }
+       {
+           journal "Journal of the Society for Industrial and Applied Mathematics" =
+       { "{\it J. Soc. Indust. Appl. Math.}" }
+       {
+           journal "Journal of the Society for Industrial and Applied Mathematics, Series B, Numerical Analysis" =
+       { "{\it J. Soc. Indust. Appl. Math. Ser. B Numer. Anal.}" }
+       {
+           journal "{SIAM} Journal on Algebraic and Discrete Methods" =
+       { "{\it {SIAM} J. Algebraic Discrete Methods}" }
+       {
+           journal "{SIAM} Journal on Applied Mathematics" =
+       { "{\it {SIAM} J. Appl. Math.}" }
+       {
+           journal "{SIAM} Journal on Computing" =
+       { "{\it {SIAM} J. Comput.}" }
+       {
+           journal "{SIAM} Journal on Matrix Analysis and Applications" =
+       { "{\it {SIAM} J. Matrix Anal. Appl.}" }
+       {
+           journal "{SIAM} Journal on Numerical Analysis" =
+       { "{\it {SIAM} J. Numer. Anal.}" }
+       {
+           journal "{SIAM} Review" =
+       { "{\it {SIAM} Rev.}" }
+       {
+           journal "{SIAM} Journal on Scientific and Statistical Computing" =
+       { "{\it {SIAM} J. Sci. Statist. Comput.}" }
+       {
+           journal "Software Practice and Experience" =
+       { "{\it Software Prac. Experience}" }
+       {
+           journal "Statistical Science" =
+       { "{\it Statist. Sci.}" }
+       {
+           journal "{USSR} Computational Mathematics and Mathematical Physics" =
+       { "{\it {U. S. S. R.} Comput. Math. and Math. Phys.}" }
+       {
+           journal "Journal of {VLSI} and Computer Systems" =
+       { "{\it J. {VLSI} Comput. Syst.}" }
+       {
+           journal "Zeitschrift fur Angewandte Mathematik und Mechanik" =
+       { "{\it Z. Angew. Math. Mech.}" }
+       {
+           journal "Zeitschrift fur Angewandte Mathematik und Physik" =
+       { "{\it Z. Angew. Math. Phys.}" }
+       {
+           journal "ACM Computing Surveys" =
+       { "{\it Comput. Surveys}" }
+       {
+           journal "ACM Transactions on Mathematical Software" =
+       { "{\it ACM Trans. Math. Software}" }
+       {
+           journal "ACM {SIGNUM} Newsletter" =
+       { "{\it ACM {SIGNUM} Newslett.}" }
+       {
+           journal "IEEE Transactions on Computers" =
+       { "{\it IEEE Trans. Comput.}" }
+       {
+           journal "IEEE Transactions on Automatic Control" =
+       { "{\it IEEE Trans. Automat. Control}" }
+       {
+           journal "Proceedings of the IEEE" =
+       { "{\it Proc. IEEE}" }
+       {
+           journal "IEEE Transactions on Aerospace and Electronic Systems" =
+       { "{\it IEEE Trans. Aerospace Electron. Systems}" }
+       {
+           journal "IMA Journal of Numerical Analysis" =
+       { "{\it IMA J. Numer. Anal.}" }
+       {
+           journal "SIAM Journal on Algebraic and Discrete Methods" =
+       { "{\it SIAM J. Algebraic Discrete Methods}" }
+       {
+           journal "SIAM Journal on Applied Mathematics" =
+       { "{\it SIAM J. Appl. Math.}" }
+       {
+           journal "SIAM Journal on Computing" =
+       { "{\it SIAM J. Comput.}" }
+       {
+           journal "SIAM Journal on Matrix Analysis and Applications" =
+       { "{\it SIAM J. Matrix Anal. Appl.}" }
+       {
+           journal "SIAM Journal on Numerical Analysis" =
+       { "{\it SIAM J. Numer. Anal.}" }
+       {
+           journal "SIAM Review" =
+       { "{\it SIAM Rev.}" }
+       {
+           journal "SIAM Journal on Scientific and Statistical Computing" =
+       { "{\it SIAM J. Sci. Statist. Comput.}" }
+       {
+           journal "USSR Computational Mathematics and Mathematical Physics" =
+       { "{\it U. S. S. R. Comput. Math. and Math. Phys.}" }
+       {
+           journal "Journal of VLSI and Computer Systems" =
+       { "{\it J. VLSI Comput. Syst.}" }
+       {
+           journal "Communications of the ACM" =
+       { "{\it Commun. ACM}" }
+       %% If no match with cases needing special handling, just output journal name
+       {  journal emphasize.with.italic.correction  }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+           }
+     if$
+     * "}" *
+         }
+    if$
+
+  number empty.or.unknown
+    {
+      volume empty.or.unknown
+        { "no number and no volume in " cite$ * warning$ "" * }
+        { " " * " \bibinfo{volume}{" * volume * "}" * }
+      if$
+    }
+    {
+      volume empty.or.unknown
+        {
+          "unusual to have number, but no volume, for " cite$ * warning$
+          " \bibinfo{number}{" * number * "}" *
+        }
+        { " \bibinfo{volume}{" * volume  * "}, \bibinfo{number}{" *
+	  number * "}" *}
+      if$
+    }
+  if$
+
+  format.day.month.year *
+}
+
+FUNCTION { format.chapter.pages }
+{
+  chapter empty.or.unknown
+    'format.pages
+    { type empty.or.unknown
+        { "Chapter" } % gnp - changed to mixed case
+        { type "t" change.case$ }
+      if$
+      chapter tie.or.space.connect
+      pages empty.or.unknown
+        {"page numbers missing in " cite$ * warning$} % gnp - added check
+        { ", " * format.pages * }
+      if$
+    }
+  if$
+}
+
+FUNCTION { format.in.emphasize.booktitle }
+{ % jtb: format for collections or proceedings not appearing in a journal
+  booktitle empty.or.unknown
+  { "" }
+  { "In " format.emphasize.booktitle * }
+  if$
+}
+
+FUNCTION { format.in.booktitle }
+{ % jtb: format for proceedings appearing in a journal
+  booktitle empty.or.unknown
+  { "" }
+  { "In \bibinfo{booktitle}{" booktitle * "}" * }
+  if$
+}
+
+FUNCTION { format.in.ed.booktitle }
+{
+  booktitle empty.or.unknown
+  { "" }
+  { editor empty.or.unknown
+    { "In " format.emphasize.booktitle * }
+                % jtb: swapped editor location
+    { "In " format.emphasize.booktitle * ", " * format.editors.fml * }
+    if$
+  }
+  if$
+}
+
+FUNCTION { format.thesis.type }
+{ % call with default type on stack top
+  type empty.or.unknown
+    'skip$    % use default type
+    {
+      pop$    % discard default type
+      % NO: it is silly to have to brace protect every degree type!:  type "t" change.case$
+      type
+    }
+  if$
+}
+
+FUNCTION { format.tr.number }
+{
+  "\bibinfo{type}{"
+  type empty.or.unknown
+    { "{T}echnical {R}eport" }  
+    'type
+  if$
+  "}" * *
+  number empty.or.unknown
+    { "t" change.case$ }
+    %% LOOKS BAD: { "." * number tie.or.space.connect }
+    %% Prefer "Research report RJ687." to "Research report. RJ687."
+    { number tie.or.space.connect }
+  if$
+}
+
+FUNCTION { format.advisor }
+{
+  advisor empty.or.unknown
+    { "" }
+    { "Advisor(s) " advisor * }
+  if$
+}
+
+FUNCTION { format.article.crossref }
+{ "See"
+  "\citeN{" * crossref * "}" *
+}
+
+FUNCTION { format.crossref.editor }
+{
+  editor #1 "{vv~}{ll}" format.name$
+  editor num.names$ duplicate$
+  #2 >
+    { pop$ " et~al\mbox{.}" * }         % jrh: avoid spacing problems
+    { #2 <
+    'skip$
+    { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+        { " et~al\mbox{.}" * }          % jrh: avoid spacing problems
+        { " and " * editor #2 "{vv~}{ll}" format.name$ * }
+      if$
+    }
+      if$
+    }
+  if$
+}
+
+FUNCTION { format.book.crossref }
+{
+  volume empty.or.unknown
+    { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
+      "In "
+    }
+    { "Volume" volume tie.or.space.connect % gnp - changed to mixed case
+      " of " *
+    }
+  if$
+  editor empty.or.unknown
+  editor field.or.null author field.or.null =
+  or
+    { key empty.or.unknown
+    { series empty.or.unknown
+        { "need editor, key, or series for " cite$ * " to crossref " *
+          crossref * warning$
+          "" *
+        }
+        { "{\em " * series * "\/}" * }
+      if$
+    }
+    { key * }
+      if$
+    }
+    { format.crossref.editor * }
+  if$
+  " \citeN{" * crossref * "}" *
+}
+
+FUNCTION { format.incoll.inproc.crossref }
+{ "See"
+  " \citeN{" * crossref * "}" *
+}
+
+FUNCTION { format.lab.names }
+{
+  % format.lab.names:
+  %
+  % determines "short" names for the abbreviated author information.
+  % "Long" labels are created in calc.label, using the routine my.full.label
+  % to format author and editor fields.
+  %
+  % There are 4 cases for labels.   (n=3 in the example)
+  % a) one author             Foo
+  % b) one to n               Foo, Bar and Baz
+  % c) use of "and others"    Foo, Bar et al.
+  % d) more than n            Foo et al.
+
+  's :=
+  s num.names$ 'numnames :=
+  numnames #2 >    % change number to number of others allowed before
+                   % forcing "et al".
+    { s #1 "{vv~}{ll}" format.name$ " et~al\mbox{.}" * } % jrh: \mbox{} added
+    {
+      numnames #1 - 'namesleft :=
+      #2 'nameptr :=
+      s #1 "{vv~}{ll}" format.name$
+        { namesleft #0 > }
+        { nameptr numnames =
+            { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" =
+                { " et~al\mbox{.}" * }          % jrh: avoid spacing problems
+                { " and " * s nameptr "{vv~}{ll}" format.name$ * }
+              if$
+            }
+            { ", " * s nameptr "{vv~}{ll}" format.name$ * }
+          if$
+          nameptr #1 + 'nameptr :=
+          namesleft #1 - 'namesleft :=
+        }
+      while$
+    }
+  if$
+}
+
+FUNCTION { author.key.label }
+{
+  author empty.or.unknown
+    { key empty.or.unknown
+          { "no key, author in " cite$ * warning$
+            cite$ #1 #3 substring$ }
+         'key
+      if$
+    }
+    { author format.lab.names }
+  if$
+}
+
+FUNCTION { author.key.organization.label }
+{ % added - gnp. Provide label formatting by organization if author is null.
+  author empty.or.unknown
+    { organization empty.or.unknown
+        { key empty.or.unknown
+            { "no key, author or organization in " cite$ * warning$
+              cite$ #1 #3 substring$ }
+            'key
+          if$
+        }
+        { organization }
+      if$
+    }
+    { author format.lab.names }
+  if$
+}
+
+FUNCTION { editor.key.organization.label }
+{ % added - gnp. Provide label formatting by organization if editor is null.
+  editor empty.or.unknown
+    { organization empty.or.unknown
+        { key empty.or.unknown
+            { "no key, editor or organization in " cite$ * warning$
+              cite$ #1 #3 substring$ }
+            'key
+          if$
+        }
+        { organization }
+      if$
+    }
+    { editor format.lab.names }
+  if$
+}
+
+FUNCTION { author.editor.key.label }
+{
+  author empty.or.unknown
+    { editor empty.or.unknown
+          { key empty.or.unknown
+               { "no key, author, or editor in " cite$ * warning$
+                 cite$ #1 #3 substring$ }
+             'key
+           if$
+         }
+          { editor format.lab.names }
+      if$
+    }
+    { author format.lab.names }
+  if$
+}
+
+FUNCTION { calc.label }
+{
+  % Changed - GNP. See also author.organization.sort, editor.organization.sort
+  % Form label for BibTeX entry. The classification of which fields are used
+  % for which type of entry (book, inbook, etc.) are taken from alpha.bst.
+  % The change here from newapa is to also include organization as a
+  % citation label if author or editor is missing.
+
+  type$ "book" =
+  type$ "inbook" =
+  or
+  type$ "periodical" =
+  or
+    'author.editor.key.label
+    { type$ "proceedings" =
+        'editor.key.organization.label
+        { type$ "manual" =
+            'author.key.organization.label
+            'author.key.label
+          if$
+        }
+      if$
+    }
+  if$
+
+  author empty.or.unknown  % generate the full label citation information.
+    {
+      editor empty.or.unknown
+        {
+          organization empty.or.unknown
+            {
+              key empty.or.unknown
+                {
+                  "no author, editor, organization, or key in " cite$ * warning$
+                  "??"
+                }
+                { key }
+              if$
+            }
+            { organization }
+          if$
+        }
+        { editor my.full.label }
+      if$
+    }
+    { author my.full.label }
+  if$
+
+  % leave label on the stack, to be popped when required.
+
+  "}{" * swap$ * "}{" *
+  %  year field.or.null purify$ #-1 #4 substring$ *
+  %
+  % save the year for sort processing afterwards (adding a, b, c, etc.)
+  %
+  year field.or.null purify$ #-1 #4 substring$
+  'label.year :=
+}
+
+
+FUNCTION { output.bibitem }
+{
+  newline$
+  "\bibitem[\protect\citeauthoryear{" write$
+  calc.label write$
+  sort.year write$
+  "}]%" writeln
+  "        {" write$
+  cite$ write$
+  "}" writeln
+  ""
+  before.all 'output.state :=
+}
+
+
+FUNCTION { output.issue.doi.coden.isxn.lccn.url.eprint }
+{ % enter and return with stack empty
+  %% We switch now from buffered output to output of complete lines, so
+  %% that the Issue .. URL data have their own lines, and are less likely
+  %% to be line-wrapped by BibTeX's short-sighted algorithm, which wraps
+  %% lines longer than 79 characters, backtracking to what it thinks is
+  %% a break point in the string.  Any such wrapping MUST be undone to
+  %% prevent percent-newline from appearing in DOIs and URLs.  The
+  %% output data are intentionally wrapped in \showxxx{} macros at
+  %% beginning of line, and that supply their own punctuation (if they
+  %% are not defined to suppress output entirely), to make it easier for
+  %% other software to recover them from .bbl files.
+  %%
+  %% It also makes it possible to later change the macro definitions
+  %% to suppress particular output values, or alter their appearance.
+  %%
+  %% Note that it is possible for theses, technical reports, and
+  %% manuals to have ISBNs, and anything that has an ISBN may also
+  %% have an ISSN.  When there are no values for these keys, there
+  %% is no output generated for them here.
+
+  "\newblock" writeln
+  after.block 'output.state :=
+
+  output.issue
+  output.isbn
+  output.coden  % CODEN is functionally like ISSN, so output them sequentially
+  output.issn
+  output.lccn
+  output.doi    % DOI is ALWAYS last according to CrossRef DOI documentation
+  output.eprint
+  output.url    % but ACM wants URL last  
+}
+
+FUNCTION { output.issue.doi.coden.isxn.lccn.url.eprint.note }
+{ % enter with stack empty, return with empty string on stack
+  output.issue.doi.coden.isxn.lccn.url.eprint
+  note empty.or.unknown
+    { }
+    {
+      "\newblock" writeln
+      output.note
+    }
+  if$
+  ""
+}
+
+FUNCTION { output.issue.doi.coden.isxn.lccn.url.eprint.note.check }
+{ % enter with stack empty, return with empty string on stack
+  output.issue.doi.coden.isxn.lccn.url.eprint
+  note empty.or.unknown
+    { }
+    {
+      "\newblock" writeln
+      output.note.check
+    }
+  if$
+  ""
+}
+
+FUNCTION { article }
+{
+  output.bibitem
+
+  author empty.or.unknown
+    {
+      editor empty.or.unknown
+        { "neither author and editor supplied for " cite$ * warning$ }
+        { format.editors "editor" output.check }
+      if$
+    }
+    { format.authors "author" output.check }
+  if$
+
+  author format.no.key output       % added
+  output.year.check                 % added
+  new.block
+  format.articletitle "title" output.check
+  new.block
+  howpublished empty.or.unknown
+    { }
+    { "\bibinfo{howpublished}{" howpublished "}" * * output }
+  if$
+
+  crossref missing$
+    { format.journal.volume.number.day.month.year }
+    {
+      "cross reference in @Article{...} is unusual" warning$
+      format.article.crossref output.nonnull
+    }
+  if$
+  output
+
+  format.pages.check.without.articleno output
+  format.articleno.numpages output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { book }
+{
+  output.bibitem
+  author empty.or.unknown
+    { format.editors "author and editor" output.check }
+    { format.authors output.nonnull
+      crossref missing$
+        { "author and editor" editor either.or.check }
+        'skip$
+      if$
+    }
+  if$
+  output.year.check       % added
+  new.block
+  format.btitle "title" output.check
+  crossref missing$
+    { new.sentence              % jtb: start a new sentence for series/volume
+      format.bvolume output
+      new.block
+      format.number.series output
+      new.sentence
+      publisher "publisher" bibinfo.output.check      
+      address "address" bibinfo.output.check    % jtb: require address
+      fin.sentence
+      pages empty.or.unknown
+        { format.bookpages }    % use bookpages when pages empty
+        { format.pages.check "pages" tie.or.space.connect }
+      if$
+      output
+    }
+    { new.block
+      format.book.crossref output.nonnull
+    }
+  if$
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { booklet }
+{
+  output.bibitem
+  format.authors output
+  author format.key output          % added
+  output.year.check                 % added
+  new.block
+  format.title "title" output.check
+  new.block
+    howpublished empty.or.unknown
+    { }
+    { "\bibinfo{howpublished}{" howpublished "}" * * output }
+  if$
+  address output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { inbook }
+{
+  output.bibitem
+  author empty.or.unknown
+    { format.editors
+      "author and editor" output.check
+    }
+    { format.authors output.nonnull
+      crossref missing$
+    { "author and editor" editor either.or.check }
+    'skip$
+      if$
+    }
+  if$
+  output.year.check                 % added
+  new.block
+  format.btitle "title" output.check
+  crossref missing$
+    { new.sentence              % jtb: start a new sentence for series/volume
+      format.bvolume output
+      new.block
+      format.number.series output
+      new.sentence
+      publisher "publisher" bibinfo.output.check
+      address "address" bibinfo.output.check    % jtb: require address
+      format.bookpages output
+      format.chapter.pages
+      "chapter and pages" output.check  % jtb: moved from before publisher
+    }
+    {
+      format.bookpages output
+      format.chapter.pages "chapter and pages" output.check
+      new.block
+      format.book.crossref output.nonnull
+    }
+  if$
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { incollection }
+{
+  output.bibitem
+  format.authors "author" output.check
+  author format.key output       % added
+  output.year.check              % added
+  new.block
+  format.articletitle "title" output.check
+  new.block
+  crossref missing$
+    { format.in.ed.booktitle "booktitle" output.check
+      new.sentence                % jtb: start a new sentence for series/volume
+      format.bvolume output
+      format.number.series output
+      new.sentence
+      publisher "publisher" bibinfo.output.check
+      address "address" bibinfo.output.check      % jtb: require address
+      format.bookpages output
+      format.chapter.pages output % gnp - was special.output.nonnull
+                                  % left out comma before page numbers
+                                  % jtb: moved from before publisher
+    }
+    {
+      format.incoll.inproc.crossref output.nonnull
+      format.chapter.pages output
+    }
+  if$
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { inproceedings }
+{
+  output.bibitem
+  format.authors "author" output.check
+  author format.key output            % added
+  output.year.check                   % added
+  new.block
+  format.articletitle "title" output.check
+  howpublished empty.or.unknown
+    { }
+    { "\bibinfo{howpublished}{" howpublished "}" * * output.dot.space }
+  if$
+  crossref missing$
+    {
+      journal missing$          % jtb: proceedings appearing in journals
+        { format.in.emphasize.booktitle format.city "booktitle"  output.check.dot.space
+          format.series output.removenospace
+          format.editors.fml output % BV 2011/09/27 Moved dot to comma
+          format.bvolume.noseries output
+          new.sentence
+          organization output
+          publisher "publisher" bibinfo.output.check % jtb: require publisher (?)
+          address "address" bibinfo.output.check  % jtb: require address
+          format.bookpages output
+        }
+        {
+           format.in.booktitle format.city "booktitle" output.check
+           format.editors.fml output
+           new.sentence
+           format.journal.volume.number.day.month.year output
+        }
+      if$
+      format.articleno output
+      format.pages.check.without.articleno output
+    }
+    {
+      format.incoll.inproc.crossref output.nonnull
+      format.articleno output
+      format.pages.check.without.articleno output
+    }
+  if$
+  format.articleno.numpages output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { conference } { inproceedings }
+
+FUNCTION { manual }
+{
+  output.bibitem
+  author empty.or.unknown
+    { editor empty.or.unknown
+      { organization "organization" output.check
+        organization format.key output }  % if all else fails, use key
+      { format.editors "author and editor" output.check }
+      if$
+    }
+    { format.authors output.nonnull }
+    if$
+  output.year.check                 % added
+  new.block
+  format.btitle "title" output.check
+  organization address new.block.checkb
+  % jtb: back to normal style: organization, address
+  organization "organization" output.check
+  address output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { mastersthesis }
+{
+  output.bibitem
+  format.authors "author" output.check
+  author format.key output          % added
+  output.year.check                 % added
+  new.block
+  format.title emphasize "title" output.check  % NB: ACM style requires emphasized thesis title
+  new.block
+  "\bibinfo{thesistype}{Master's\ thesis}" format.thesis.type output
+  new.sentence  
+  school "school" bibinfo.output.check
+  address empty.or.unknown
+     { }
+     { "\bibinfo{address}{" address * "}" * output }
+  if$
+  new.block
+  format.advisor output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { misc }
+{
+  output.bibitem
+  format.authors output
+  author format.key output            % added
+  output.year.check                   % added
+  title howpublished new.block.checkb
+  format.title output
+  new.block
+  howpublished empty.or.unknown
+    { }
+    { "\bibinfo{howpublished}{" howpublished "}" * * output }
+  if$
+  "" output.nonnull.dot.space
+  output.day.month.year      
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { online } { misc }
+
+FUNCTION { game } { misc }
+
+
+FUNCTION { phdthesis }
+{
+  output.bibitem
+  format.authors "author" output.check
+  author format.key output          % added
+  output.year.check                 % added
+  new.block
+  format.title emphasize "title" output.check  % NB: ACM style requires emphasized thesis title
+  new.block
+ "\bibinfo{thesistype}{Ph.D. Dissertation}" format.thesis.type output
+ new.sentence 
+  school "school" bibinfo.output.check
+  address empty.or.unknown
+     { }
+     { "\bibinfo{address}{" address * "}" * output }
+  if$
+  new.block
+  format.advisor output
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION {format.date}
+{ year empty.or.unknown
+    { month empty.or.unknown
+        {
+          ""                    % output empty date if year/month both empty
+          day empty.or.unknown
+            {  }
+            { "there's a day but no month or year in " cite$ * warning$ }
+          if$
+        }
+        { "there's a month but no year in " cite$ * warning$
+          month
+          day empty.or.unknown
+            { }
+            { " " * day * }
+          if$
+        }
+      if$
+    }
+    { month empty.or.unknown
+        {
+          year                  % output only year if month empty
+          day empty.or.unknown
+            {  }
+            { "there's a day and year but no month in " cite$ * warning$ }
+          if$
+        }
+        {
+          month " " *
+          day empty.or.unknown
+            { }
+            { day * ", " * }
+          if$
+          year *
+        }
+      if$
+    }
+  if$
+}
+
+FUNCTION {new.block.checka}
+{
+  empty.or.unknown
+    'skip$
+    'new.block
+  if$
+}
+
+FUNCTION { periodical }
+{
+  output.bibitem
+  editor empty.or.unknown
+    { organization output }
+    { format.editors output.nonnull }
+  if$
+  new.block
+  output.year.check  
+  new.sentence
+  format.articletitle "title" output.check
+  format.journal.volume.number.day.month.year output
+  fin.entry
+}
+
+FUNCTION { proceedings }
+{
+  output.bibitem
+  editor empty.or.unknown
+    { organization output
+      organization format.key output }  % gnp - changed from author format.key
+    { format.editors output.nonnull }
+  if$
+  % author format.key output             % gnp - removed (should be either
+  %                                        editor or organization
+  output.year.check                    % added (newapa)
+  new.block
+  format.btitle format.city "title" output.check        % jtb: added city
+  new.sentence
+  format.bvolume output
+  format.number.series output
+  new.sentence
+  organization output
+  % jtb: normal order: publisher, address
+  publisher empty.or.unknown
+     { }
+     { "\bibinfo{publisher}{" publisher * "}" * output }
+  if$
+  address empty.or.unknown
+     { }
+     { "\bibinfo{address}{" address * "}" * output }
+  if$
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { techreport }
+{
+  output.bibitem
+  format.authors "author" output.check
+  author format.key output             % added
+  output.year.check                    % added
+  new.block
+  format.btitle "title" output.check
+  new.block
+%   format.tr.number output               % jtb: moved month ...
+  format.tr.number output new.sentence    % Gerry  - need dot 2011/09/28
+  institution "institution" bibinfo.output.check
+  address empty.or.unknown
+    { }
+    { "\bibinfo{address}{" address "}" * * output }
+  if$
+  new.sentence
+  format.named.pages output
+  % ACM omits year at end in transactions style
+  % format.day.month.year output.nonnull.dot.space  % jtb: ... to here (no parens)
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note
+  fin.entry
+}
+
+FUNCTION { unpublished }
+{
+  output.bibitem
+  format.authors
+  "author" output.check
+  author format.key output              % added
+  output.year.check                     % added
+  new.block
+  format.title "title" output.check
+  fin.sentence
+  output.day.month.year                 % UTAH
+  fin.block
+  output.issue.doi.coden.isxn.lccn.url.eprint.note.check
+  fin.entry
+}
+
+FUNCTION { default.type } { misc }
+
+%%% ACM journal-style month definitions: full name if 1--5 letters, else
+%%% abbreviation of 3 or 4 characters and a dot
+
+MACRO {jan}             {"Jan."}
+
+MACRO {feb}             {"Feb."}
+
+MACRO {mar}             {"March"}
+
+MACRO {apr}             {"April"}
+
+MACRO {may}             {"May"}
+
+MACRO {jun}             {"June"}
+
+MACRO {jul}             {"July"}
+
+MACRO {aug}             {"Aug."}
+
+MACRO {sep}             {"Sept."}
+
+MACRO {oct}             {"Oct."}
+
+MACRO {nov}             {"Nov."}
+
+MACRO {dec}             {"Dec."}
+
+
+%%% ====================================================================
+%%%                 I M P O R T A N T   C H A N G E
+%%%
+%%% For the 2009 release of the official acm-*.bst files, there are to
+%%% be NO predefined journal abbreviations in those style files.
+%%%
+%%% ACM may later develop an official list of mappings of full journal
+%%% names of commonly-cited journals to ACM-preferred abbreviations, but
+%%% authors should consider that use of any of these commented-out
+%%% abbreviations is DEPRECATED unless the BibTeX file itself provides
+%%% its own @String{name = "value"} definitions.
+%%%
+%%% Use of journal (and publisher and address) @String{...}
+%%% abbreviations, as opposed to explicit value assignments such as
+%%% journal = "J. ACM" and publisher = "IEEE", is preferred in
+%%% bibliographic databases, because it makes it easier for journal
+%%% production staff to replace those definitions by publisher-preferred
+%%% abbreviations when articles are typeset for publication.
+%%%
+%%% For historical reasons, and because some of these abbreviations are
+%%% used in other (non-ACM) bibliography style files, they are preserved
+%%% here in comments.  Future releases of the acm*-.bst files are likely
+%%% to remove them entirely.
+%%% ====================================================================
+%%%
+%%% DEPRECATED: MACRO {acmcs}           {"ACM Comput. Surv."}                   % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {acmlett}         {"ACM Lett. Program. Lang. Syst."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {acta}            {"Acta Inf."}                           % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ai}              {"Artificial Intelligence"}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {al}              {"Ada Lett."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {acr}             {"Adv. Comput. Res."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {bit}             {"Bit"}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {cacm}            {"Commun. ACM"}                         % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {cj}              {"Comput. J."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {cn}              {"Comput. Netw."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {cl}              {"Comput. Lang."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ibmjrd}          {"IBM J. Res. and Development"}         % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ibmsj}           {"IBM Systems Journal"}                 % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ict}             {"Inf. Contr."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieebcs}          {"IEE/BCS Softw. Eng. J."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieees}           {"IEEE Softw."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieeese}          {"IEEE Trans. Softw. Eng."}             % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieeetc}          {"IEEE Trans. Comput."}                 % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieeetcad}        {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieeetpds}        {"IEEE Trans. Parall. Distrib. Syst."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ieeetit}         {"IEEE Trans. Inf. Theory"}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ipl}             {"Inf. Process. Lett."}                 % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {icp}             {"Inf. Comput."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ist}             {"Inf. Softw. Tech."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ijsa}            {"Int. J. Supercomput. Appl."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ijpp}            {"Int. J. Parallel Program."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jacm}            {"J. ACM"}                              % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: % MACRO {jcss}          {"Journal of Computer and System Sciences"} % original BibTeX
+%%% DEPRECATED: MACRO {jcss}            {"J. Comput. Syst. Sci."}               % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jlp}             {"J. Logic Program."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jfp}             {"J. Funct. Program."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jsmrp}           {"J. Softw. Maint. Res. Pract."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jss}             {"J. Syst. Softw."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jlc}             {"J. Logic and Comput."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {jlsc}            {"J. Lisp Symb. Comput."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {lpls}            {"Lett. Program. Lang. Syst."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {mor}             {"Math. Oper. Res."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {mscs}            {"Math. Struct. Comput. Sci."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {mst}             {"Math. Syst. Theor."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {ngc}             {"New Gen. Comput."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {scp}             {"Sci. Comput. Program."}               % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {sicomp}          {"SIAM J. Comput."}                     % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {spe}             {"Softw. Pract. Exper."}
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {tocs}            {"ACM Trans. Comput. Syst."}            % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {tods}            {"ACM Trans. Database Syst."}           % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {tog}             {"ACM Trans. Graphics"}                 % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {toms}            {"ACM Trans. Math. Softw."}             % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {toois}           {"ACM Trans. Office Inf. Syst."}        % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {toplas}          {"ACM Trans. Program. Lang. Syst."}     % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {tcs}             {"Theor. Comput. Sci."}                 % original BibTeX
+%%% DEPRECATED:
+%%% DEPRECATED: MACRO {tr}              {"Tech. Rep."}
+%%% ====================================================================
+
+READ
+
+FUNCTION { sortify }
+{
+  purify$
+  "l" change.case$
+}
+
+FUNCTION { chop.word }
+{
+  's :=
+  'len :=
+  s #1 len substring$ =
+    { s len #1 + global.max$ substring$ }
+    's
+  if$
+}
+
+FUNCTION { sort.format.names }
+{
+  's :=
+  #1 'nameptr :=
+  ""
+  s num.names$ 'numnames :=
+  numnames 'namesleft :=
+    { namesleft #0 > }
+    { nameptr #1 >
+          { "   " * }
+         'skip$
+      if$
+  %      s nameptr "{ff{ } }{ll{ }}{  vv{ }}{  jj{ }}" format.name$ 't :=
+      s nameptr "{vv{ } }{ll{ }}{  f{ }}{  jj{ }}" format.name$ 't :=
+      nameptr numnames = t "others" = and
+          { " et~al" * }
+          { t sortify * }
+      if$
+      nameptr #1 + 'nameptr :=
+      namesleft #1 - 'namesleft :=
+    }
+  while$
+}
+
+FUNCTION { sort.format.title }
+{
+  't :=
+  "A " #2
+    "An " #3
+      "The " #4 t chop.word
+    chop.word
+  chop.word
+  sortify
+  #1 global.max$ substring$
+}
+
+FUNCTION { author.sort }
+{
+  author empty.or.unknown
+    { key empty.or.unknown
+         { "to sort, need author or key in " cite$ * warning$
+           "" }
+         { key sortify }
+      if$
+    }
+    { author sort.format.names }
+  if$
+}
+
+FUNCTION { author.editor.sort }
+{
+  author empty.or.unknown
+    {
+      editor empty.or.unknown
+         {
+           key empty.or.unknown
+             { "to sort, need author, editor, or key in " cite$ * warning$
+               ""
+             }
+             { key sortify }
+           if$
+         }
+         { editor sort.format.names }
+      if$
+    }
+    { author sort.format.names }
+  if$
+}
+
+FUNCTION { author.organization.sort }
+{
+  % added - GNP. Stack author or organization for sorting (from alpha.bst).
+  % Unlike alpha.bst, we need entire names, not abbreviations
+
+  author empty.or.unknown
+    { organization empty.or.unknown
+        { key empty.or.unknown
+            { "to sort, need author, organization, or key in " cite$ * warning$
+              ""
+            }
+            { key sortify }
+          if$
+        }
+        { organization sortify }
+      if$
+    }
+    { author sort.format.names }
+  if$
+}
+
+FUNCTION { editor.organization.sort }
+{
+  % added - GNP. Stack editor or organization for sorting (from alpha.bst).
+  % Unlike alpha.bst, we need entire names, not abbreviations
+
+  editor empty.or.unknown
+    { organization empty.or.unknown
+        { key empty.or.unknown
+            { "to sort, need editor, organization, or key in " cite$ * warning$
+              ""
+            }
+            { key sortify }
+          if$
+        }
+        { organization sortify }
+      if$
+    }
+    { editor sort.format.names }
+  if$
+}
+
+FUNCTION { presort }
+{
+  % Presort creates the bibentry's label via a call to calc.label, and then
+  % sorts the entries based on entry type. Chicago.bst adds support for
+  % including organizations as the sort key; the following is stolen from
+  % alpha.bst.
+
+  calc.label sortify % recalculate bibitem label
+  year field.or.null purify$ #-1 #4 substring$ * % add year
+  "    "
+  *
+  type$ "book" =
+  type$ "inbook" =
+  or
+    'author.editor.sort
+    { type$ "proceedings" =
+        'editor.organization.sort
+        { type$ "manual" =
+            'author.organization.sort
+            'author.sort
+          if$
+        }
+      if$
+    }
+  if$
+  #1 entry.max$ substring$        % added for newapa
+  'sort.label :=                  % added for newapa
+  sort.label                      % added for newapa
+  *
+  "    "
+  *
+  title field.or.null
+  sort.format.title
+  *
+  #1 entry.max$ substring$
+  'sort.key$ :=
+}
+
+ITERATE { presort }
+
+SORT             % by label, year, author/editor, title
+
+FUNCTION { initialize.extra.label.stuff }
+{ #0 int.to.chr$ 'last.label :=
+  "" 'next.extra :=
+  #0 'last.extra.num :=
+}
+
+FUNCTION { forward.pass }
+{
+  % Pass through all entries, comparing current entry to last one.
+  % Need to concatenate year to the stack (done by calc.label) to determine
+  % if two entries are the same (see presort)
+
+  last.label
+  % OLD:calc.label year field.or.null purify$ #-1 #4 substring$ * % add year
+  % NEW:
+  author.key.label year field.or.null purify$ #-1 #4 substring$ * % add year
+  #1 entry.max$ substring$ =     % are they equal?
+     { last.extra.num #1 + 'last.extra.num :=
+       last.extra.num int.to.chr$ 'extra.label :=
+     }
+     { "a" chr.to.int$ 'last.extra.num :=
+       "" 'extra.label :=
+       % OLD: calc.label year field.or.null purify$ #-1 #4 substring$ * % add year
+       % NEW:
+       author.key.label year field.or.null purify$ #-1 #4 substring$ * % add year
+       #1 entry.max$ substring$ 'last.label := % assign to last.label
+     }
+  if$
+}
+
+FUNCTION { reverse.pass }
+{
+  next.extra "b" =
+    { "a" 'extra.label := }
+     'skip$
+  if$
+  label.year extra.label * 'sort.year :=
+  extra.label 'next.extra :=
+}
+
+EXECUTE {initialize.extra.label.stuff}
+
+ITERATE {forward.pass}
+
+REVERSE {reverse.pass}
+
+FUNCTION { bib.sort.order }
+{
+  sort.label
+  "    "
+  *
+  year field.or.null sortify
+  *
+  "    "
+  *
+  title field.or.null
+  sort.format.title
+  *
+  #1 entry.max$ substring$
+  'sort.key$ :=
+}
+
+ITERATE { bib.sort.order }
+
+SORT             % by sort.label, year, title --- giving final bib. order.
+
+FUNCTION { begin.bib }
+{
+  %% Set to #0 show 13-digit ISBN in preference to 10-digit ISBN.
+  %% Set to #1 to show both 10-digit and 13-digit ISBNs.
+  #1 'show-isbn-10-and-13 :=
+
+  "%%% -*-BibTeX-*-" writeln
+  "%%% Do NOT edit. File created by BibTeX with style" writeln
+  "%%% ACM-Reference-Format-Journals [18-Jan-2012]." writeln
+  "" writeln
+
+  preamble$ empty.or.unknown
+    'skip$
+    { preamble$ writeln }
+  if$
+  "\begin{thebibliography}{00}" writeln
+  ""                                                                         writeln
+  "%%% ====================================================================" writeln
+  "%%% NOTE TO THE USER: you can override these defaults by providing"       writeln
+  "%%% customized versions of any of these macros before the \bibliography"  writeln
+  "%%% command.  Each of them MUST provide its own final punctuation,"       writeln
+  "%%% except for \shownote{}, \showDOI{}, and \showURL{}.  The latter two"  writeln
+  "%%% do not use final punctuation, in order to avoid confusing it with"    writeln
+  "%%% the Web address."                                                     writeln
+  "%%%"                                                                      writeln
+  "%%% To suppress output of a particular field, define its macro to expand" writeln
+  "%%% to an empty string, or better, \unskip, like this:"                   writeln
+  "%%%"                                                                      writeln
+  "%%% \newcommand{\showDOI}[1]{\unskip}   % LaTeX syntax"                   writeln
+  "%%%"                                                                      writeln
+  "%%% \def \showDOI #1{\unskip}           % plain TeX syntax"               writeln
+  "%%%"                                                                      writeln
+  "%%% ====================================================================" writeln
+  ""                                                                         writeln
+
+  %% ACM publications do not use CODEN, ISSN, and LCCN data, so their default
+  %% macro wrappers expand to \unskip, discarding their values and unwanted
+  %% space.
+  %%
+  %% For other publications, prior definitions like these may be useful:
+  %%
+  %%     Plain TeX:
+  %%         \def \showCODEN     #1{CODEN #1.}
+  %%         \def \showISSN      #1{ISSN #1.}
+  %%         \def \showLCCN      #1{LCCN #1.}
+  %%
+  %%     LaTeX:
+  %%         \newcommand{\showCODEN}[1]{CODEN #1.}
+  %%         \newcommand{\showISSN}[1]#1{ISSN #1.}
+  %%         \newcommand{\showLCCN}[1]{LCCN #1.}
+
+  "\ifx \showCODEN    \undefined \def \showCODEN     #1{\unskip}     \fi" writeln
+  "\ifx \showDOI      \undefined \def \showDOI       #1{{\tt DOI:}\penalty0{#1}\ } \fi" writeln
+  % ACM styles omit ISBNs, but they can be included by suitable definitions of
+  % \showISBNx and \showISBNxiii before the .bbl file is read
+  "\ifx \showISBNx    \undefined \def \showISBNx     #1{\unskip}     \fi" writeln
+  "\ifx \showISBNxiii \undefined \def \showISBNxiii  #1{\unskip}     \fi" writeln
+  "\ifx \showISSN     \undefined \def \showISSN      #1{\unskip}     \fi" writeln
+  "\ifx \showLCCN     \undefined \def \showLCCN      #1{\unskip}     \fi" writeln
+  "\ifx \shownote     \undefined \def \shownote      #1{#1}          \fi" writeln % NB: final period supplied by add.period$ above
+  "\ifx \showarticletitle \undefined \def \showarticletitle #1{#1}   \fi" writeln
+  "\ifx \showURL      \undefined \def \showURL       #1{#1}          \fi" writeln
+  "% The following commands are used for tagged output and should be " writeln
+  "% invisible to TeX" writeln
+  "\providecommand\bibfield[2]{#2}" writeln
+  "\providecommand\bibinfo[2]{#2}" writeln
+  "\providecommand\natexlab[1]{#1}" writeln
+  "\providecommand\showeprint[2][]{arXiv:#2}" writeln
+}
+
+EXECUTE {begin.bib}
+
+EXECUTE {init.state.consts}
+
+ITERATE {call.type$}
+
+FUNCTION { end.bib }
+{
+  newline$
+  "\end{thebibliography}"
+  writeln
+}
+
+EXECUTE {end.bib}
+
+
+
Index: doc/papers/OOPSLA17/Makefile
===================================================================
--- doc/papers/OOPSLA17/Makefile	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/Makefile	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,83 @@
+## Define the appropriate configuration variables.
+
+TeXLIB = .:../LaTeXmacros:../LaTeXmacros/listings:../LaTeXmacros/enumitem:../bibliography/:
+LaTeX  = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex -halt-on-error
+BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex
+
+## Define the text source files.
+
+SOURCES = ${addsuffix .tex, \
+generic_types \
+}
+
+FIGURES = ${addsuffix .tex, \
+}
+
+PICTURES = ${addsuffix .pstex, \
+}
+
+PROGRAMS = ${addsuffix .tex, \
+}
+
+GRAPHS = ${addsuffix .tex, \
+timing \
+}
+
+## Define the documents that need to be made.
+
+DOCUMENT = generic_types.pdf
+
+# Directives #
+
+all : ${DOCUMENT}
+
+clean :
+	rm -f *.bbl *.aux *.dvi *.idx *.ilg *.ind *.brf *.out *.log *.toc *.blg *.pstex_t *.cf \
+		${FIGURES} ${PICTURES} ${PROGRAMS} ${GRAPHS} ${basename ${DOCUMENT}}.ps ${DOCUMENT}
+
+# File Dependencies #
+
+${DOCUMENT} : ${basename ${DOCUMENT}}.ps
+	ps2pdf $<
+
+${basename ${DOCUMENT}}.ps : ${basename ${DOCUMENT}}.dvi
+	dvips $< -o $@
+
+#${DOCUMENT} : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \
+
+${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ../bibliography/cfa.bib
+	# Conditionally create an empty *.idx (index) file for inclusion until makeindex is run.
+	if [ ! -r ${basename $@}.idx ] ; then touch ${basename $@}.idx ; fi
+	# Must have *.aux file containing citations for bibtex
+	if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
+	-${BibTeX} ${basename $@}
+	# Some citations reference others so run steps again to resolve these citations
+	${LaTeX} ${basename $@}.tex
+	-${BibTeX} ${basename $@}
+	# Make index from *.aux entries and input index at end of document
+	makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx
+	${LaTeX} ${basename $@}.tex
+	# Run again to get index title into table of contents
+	${LaTeX} ${basename $@}.tex
+
+predefined :
+	sed -f predefined.sed ${basename ${DOCUMENT}}.tex > ${basename $@}.cf
+
+## Define the default recipes.
+
+${GRAPHS} : evaluation/timing.gp evaluation/timing.dat
+	gnuplot evaluation/timing.gp
+
+%.tex : %.fig
+	fig2dev -L eepic $< > $@
+
+%.ps : %.fig
+	fig2dev -L ps $< > $@
+
+%.pstex : %.fig
+	fig2dev -L pstex $< > $@
+	fig2dev -L pstex_t -p $@ $< > $@_t
+
+# Local Variables: #
+# compile-command: "make" #
+# End: #
Index: doc/papers/OOPSLA17/acmart-pacmpl-template.tex
===================================================================
--- doc/papers/OOPSLA17/acmart-pacmpl-template.tex	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/acmart-pacmpl-template.tex	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,217 @@
+%% For double-blind review submission
+\documentclass[acmlarge,review,anonymous]{acmart}\settopmatter{printfolios=true}
+%% For single-blind review submission
+%\documentclass[acmlarge,review]{acmart}\settopmatter{printfolios=true}
+%% For final camera-ready submission
+%\documentclass[acmlarge]{acmart}\settopmatter{}
+
+%% Note: Authors migrating a paper from PACMPL format to traditional
+%% SIGPLAN proceedings format should change 'acmlarge' to
+%% 'sigplan,10pt'.
+
+
+%% Some recommended packages.
+\usepackage{booktabs}   %% For formal tables:
+                        %% http://ctan.org/pkg/booktabs
+\usepackage{subcaption} %% For complex figures with subfigures/subcaptions
+                        %% http://ctan.org/pkg/subcaption
+
+
+\makeatletter\if@ACM@journal\makeatother
+%% Journal information (used by PACMPL format)
+%% Supplied to authors by publisher for camera-ready submission
+\acmJournal{PACMPL}
+\acmVolume{1}
+\acmNumber{1}
+\acmArticle{1}
+\acmYear{2017}
+\acmMonth{1}
+\acmDOI{10.1145/nnnnnnn.nnnnnnn}
+\startPage{1}
+\else\makeatother
+%% Conference information (used by SIGPLAN proceedings format)
+%% Supplied to authors by publisher for camera-ready submission
+\acmConference[PL'17]{ACM SIGPLAN Conference on Programming Languages}{January 01--03, 2017}{New York, NY, USA}
+\acmYear{2017}
+\acmISBN{978-x-xxxx-xxxx-x/YY/MM}
+\acmDOI{10.1145/nnnnnnn.nnnnnnn}
+\startPage{1}
+\fi
+
+
+%% Copyright information
+%% Supplied to authors (based on authors' rights management selection;
+%% see authors.acm.org) by publisher for camera-ready submission
+\setcopyright{none}             %% For review submission
+%\setcopyright{acmcopyright}
+%\setcopyright{acmlicensed}
+%\setcopyright{rightsretained}
+%\copyrightyear{2017}           %% If different from \acmYear
+
+
+%% Bibliography style
+\bibliographystyle{ACM-Reference-Format}
+%% Citation style
+%% Note: author/year citations are required for papers published as an
+%% issue of PACMPL.
+\citestyle{acmauthoryear}   %% For author/year citations
+
+
+
+\begin{document}
+
+%% Title information
+\title[Short Title]{Full Title}         %% [Short Title] is optional;
+                                        %% when present, will be used in
+                                        %% header instead of Full Title.
+\titlenote{with title note}             %% \titlenote is optional;
+                                        %% can be repeated if necessary;
+                                        %% contents suppressed with 'anonymous'
+\subtitle{Subtitle}                     %% \subtitle is optional
+\subtitlenote{with subtitle note}       %% \subtitlenote is optional;
+                                        %% can be repeated if necessary;
+                                        %% contents suppressed with 'anonymous'
+
+
+%% Author information
+%% Contents and number of authors suppressed with 'anonymous'.
+%% Each author should be introduced by \author, followed by
+%% \authornote (optional), \orcid (optional), \affiliation, and
+%% \email.
+%% An author may have multiple affiliations and/or emails; repeat the
+%% appropriate command.
+%% Many elements are not rendered, but should be provided for metadata
+%% extraction tools.
+
+%% Author with single affiliation.
+\author{First1 Last1}
+\authornote{with author1 note}          %% \authornote is optional;
+                                        %% can be repeated if necessary
+\orcid{nnnn-nnnn-nnnn-nnnn}             %% \orcid is optional
+\affiliation{
+  \position{Position1}
+  \department{Department1}              %% \department is recommended
+  \institution{Institution1}            %% \institution is required
+  \streetaddress{Street1 Address1}
+  \city{City1}
+  \state{State1}
+  \postcode{Post-Code1}
+  \country{Country1}
+}
+\email{first1.last1@inst1.edu}          %% \email is recommended
+
+%% Author with two affiliations and emails.
+\author{First2 Last2}
+\authornote{with author2 note}          %% \authornote is optional;
+                                        %% can be repeated if necessary
+\orcid{nnnn-nnnn-nnnn-nnnn}             %% \orcid is optional
+\affiliation{
+  \position{Position2a}
+  \department{Department2a}             %% \department is recommended
+  \institution{Institution2a}           %% \institution is required
+  \streetaddress{Street2a Address2a}
+  \city{City2a}
+  \state{State2a}
+  \postcode{Post-Code2a}
+  \country{Country2a}
+}
+\email{first2.last2@inst2a.com}         %% \email is recommended
+\affiliation{
+  \position{Position2b}
+  \department{Department2b}             %% \department is recommended
+  \institution{Institution2b}           %% \institution is required
+  \streetaddress{Street3b Address2b}
+  \city{City2b}
+  \state{State2b}
+  \postcode{Post-Code2b}
+  \country{Country2b}
+}
+\email{first2.last2@inst2b.org}         %% \email is recommended
+
+
+%% Paper note
+%% The \thanks command may be used to create a "paper note" ---
+%% similar to a title note or an author note, but not explicitly
+%% associated with a particular element.  It will appear immediately
+%% above the permission/copyright statement.
+\thanks{with paper note}                %% \thanks is optional
+                                        %% can be repeated if necesary
+                                        %% contents suppressed with 'anonymous'
+
+
+%% Abstract
+%% Note: \begin{abstract}...\end{abstract} environment must come
+%% before \maketitle command
+\begin{abstract}
+Text of abstract \ldots.
+\end{abstract}
+
+
+%% 2012 ACM Computing Classification System (CSS) concepts
+%% Generate at 'http://dl.acm.org/ccs/ccs.cfm'.
+\begin{CCSXML}
+<ccs2012>
+<concept>
+<concept_id>10011007.10011006.10011008</concept_id>
+<concept_desc>Software and its engineering~General programming languages</concept_desc>
+<concept_significance>500</concept_significance>
+</concept>
+<concept>
+<concept_id>10003456.10003457.10003521.10003525</concept_id>
+<concept_desc>Social and professional topics~History of programming languages</concept_desc>
+<concept_significance>300</concept_significance>
+</concept>
+</ccs2012>
+\end{CCSXML}
+
+\ccsdesc[500]{Software and its engineering~General programming languages}
+\ccsdesc[300]{Social and professional topics~History of programming languages}
+%% End of generated code
+
+
+%% Keywords
+%% comma separated list
+\keywords{keyword1, keyword2, keyword3}  %% \keywords is optional
+
+
+%% \maketitle
+%% Note: \maketitle command must come after title commands, author
+%% commands, abstract environment, Computing Classification System
+%% environment and commands, and keywords command.
+\maketitle
+
+
+\section{Introduction}
+
+Text of paper \ldots
+
+
+%% Acknowledgments
+\begin{acks}                            %% acks environment is optional
+                                        %% contents suppressed with 'anonymous'
+  %% Commands \grantsponsor{<sponsorID>}{<name>}{<url>} and
+  %% \grantnum[<url>]{<sponsorID>}{<number>} should be used to
+  %% acknowledge financial support and will be used by metadata
+  %% extraction tools.
+  This material is based upon work supported by the
+  \grantsponsor{GS100000001}{National Science
+    Foundation}{http://dx.doi.org/10.13039/100000001} under Grant
+  No.~\grantnum{GS100000001}{nnnnnnn} and Grant
+  No.~\grantnum{GS100000001}{mmmmmmm}.  Any opinions, findings, and
+  conclusions or recommendations expressed in this material are those
+  of the author and do not necessarily reflect the views of the
+  National Science Foundation.
+\end{acks}
+
+
+%% Bibliography
+%\bibliography{bibfile}
+
+
+%% Appendix
+\appendix
+\section{Appendix}
+
+Text of appendix \ldots
+
+\end{document}
Index: doc/papers/OOPSLA17/acmart.cls
===================================================================
--- doc/papers/OOPSLA17/acmart.cls	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/acmart.cls	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,2188 @@
+%%
+%% This is file `acmart.cls',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% acmart.dtx  (with options: `class')
+%% 
+%% IMPORTANT NOTICE:
+%% 
+%% For the copyright see the source file.
+%% 
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from acmart.cls.
+%% 
+%% For distribution of the original source see the terms
+%% for copying and modification in the file acmart.dtx.
+%% 
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{acmart}
+[2016/12/03 v1.25 Typesetting articles for Association of
+Computing Machinery]
+\def\@classname{acmart}
+\RequirePackage{xkeyval}
+\define@choicekey*+{acmart.cls}{format}[\ACM@format\ACM@format@nr]{%
+  manuscript, acmsmall, acmlarge, acmtog, sigconf, siggraph,
+  sigplan, sigchi, sigchi-a}[manuscript]{}{%
+  \ClassError{\@classname}{The option format must be manuscript,
+    acmsmall, acmlarge, acmtog, sigconf, siggraph,
+    sigplan, sigchi or sigchi-a}}
+\def\@DeclareACMFormat#1{\DeclareOptionX{#1}{\setkeys{acmart.cls}{format=#1}}}
+\@DeclareACMFormat{manuscript}
+\@DeclareACMFormat{acmsmall}
+\@DeclareACMFormat{acmlarge}
+\@DeclareACMFormat{acmtog}
+\@DeclareACMFormat{sigconf}
+\@DeclareACMFormat{siggraph}
+\@DeclareACMFormat{sigplan}
+\@DeclareACMFormat{sigchi}
+\@DeclareACMFormat{sigchi-a}
+\ExecuteOptionsX{format}
+\define@boolkey+{acmart.cls}[@ACM@]{screen}[true]{%
+  \if@ACM@screen
+    \PackageInfo{\@classname}{Using screen mode}%
+  \else
+    \PackageInfo{\@classname}{Not using screen mode}%
+  \fi}{\PackageError{\@classname}{Option screen can be either true or
+    false}}
+\ExecuteOptionsX{screen=false}
+\define@boolkey+{acmart.cls}[@ACM@]{review}[true]{%
+  \if@ACM@review
+    \PackageInfo{\@classname}{Using review mode}%
+  \else
+    \PackageInfo{\@classname}{Not using review mode}%
+  \fi}{\PackageError{\@classname}{Option review can be either true or
+    false}}
+\ExecuteOptionsX{review=false}
+\define@boolkey+{acmart.cls}[@ACM@]{authorversion}[true]{%
+  \if@ACM@authorversion
+    \PackageInfo{\@classname}{Using authorversion mode}%
+  \else
+    \PackageInfo{\@classname}{Not using authorversion mode}%
+  \fi}{\PackageError{\@classname}{Option authorversion can be either true or
+    false}}
+\ExecuteOptionsX{authorversion=false}
+\newif\if@ACM@natbib@override
+\@ACM@natbib@overridefalse
+\define@boolkey+{acmart.cls}[@ACM@]{natbib}[true]{%
+  \@ACM@natbib@overridetrue
+  \if@ACM@natbib
+    \PackageInfo{\@classname}{Explicitly selecting natbib mode}%
+  \else
+    \PackageInfo{\@classname}{Explicitly deselecting natbib mode}%
+  \fi}{\PackageError{\@classname}{Option natbib can be either true or
+    false}}
+\define@boolkey+{acmart.cls}[@ACM@]{anonymous}[true]{%
+  \if@ACM@anonymous
+    \PackageInfo{\@classname}{Using anonymous mode}%
+  \else
+    \PackageInfo{\@classname}{Not using anonymous mode}%
+  \fi}{\PackageError{\@classname}{Option anonymous can be either true or
+    false}}
+\ExecuteOptionsX{anonymous=false}
+\def\ACM@fontsize{}
+\DeclareOptionX{9pt}{\edef\ACM@fontsize{\CurrentOption}}
+\DeclareOptionX{10pt}{\edef\ACM@fontsize{\CurrentOption}}
+\DeclareOptionX{11pt}{\edef\ACM@fontsize{\CurrentOption}}
+\DeclareOptionX{12pt}{\edef\ACM@fontsize{\CurrentOption}}
+\DeclareOptionX{draft}{\PassOptionsToClass{\CurrentOption}{amsart}}
+\DeclareOptionX{*}{\PassOptionsToClass{\CurrentOption}{amsart}}
+\ProcessOptionsX
+\ClassInfo{\@classname}{Using format \ACM@format, number \ACM@format@nr}
+\newif\if@ACM@manuscript
+\newif\if@ACM@journal
+\newif\if@ACM@sigchiamode
+\ifnum\ACM@format@nr=0\relax
+  \@ACM@manuscripttrue
+\else
+  \@ACM@manuscriptfalse
+\fi
+\@ACM@sigchiamodefalse
+\ifcase\ACM@format@nr
+\relax % manuscript
+  \@ACM@journaltrue
+\or % acmsmall
+  \@ACM@journaltrue
+\or % acmlarge
+  \@ACM@journaltrue
+\or % acmtog
+  \@ACM@journaltrue
+\or % sigconf
+  \@ACM@journalfalse
+\or % siggraph
+  \@ACM@journalfalse
+ \or % sigplan
+  \@ACM@journalfalse
+ \or % sigchi
+  \@ACM@journalfalse
+\or % sigchi-a
+  \@ACM@journalfalse
+  \@ACM@sigchiamodetrue
+\fi
+\if@ACM@natbib@override\else
+    \@ACM@natbibtrue
+\fi
+\ifx\ACM@fontsize\@empty
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \def\ACM@fontsize{9pt}%
+  \or % acmsmall
+    \def\ACM@fontsize{10pt}%
+  \or % acmlarge
+    \def\ACM@fontsize{10pt}%
+  \or % acmtog
+    \def\ACM@fontsize{9pt}%
+  \or % sigconf
+    \def\ACM@fontsize{9pt}%
+  \or % siggraph
+    \def\ACM@fontsize{9pt}%
+   \or % sigplan
+    \def\ACM@fontsize{9pt}%
+   \or % sigchi
+    \def\ACM@fontsize{10pt}%
+  \or % sigchi-a
+    \def\ACM@fontsize{10pt}%
+  \fi
+\fi
+\ClassInfo{\@classname}{Using fontsize \ACM@fontsize}
+\LoadClass[\ACM@fontsize, reqno]{amsart}
+\RequirePackage{microtype}
+\RequirePackage{totpages}
+\RequirePackage{environ}
+\if@ACM@manuscript
+\RequirePackage{setspace}
+\onehalfspacing
+\fi
+\if@ACM@natbib
+  \RequirePackage{natbib}
+  \renewcommand{\bibsection}{%
+     \section*{\refname}%
+     \phantomsection\addcontentsline{toc}{section}{\refname}%
+  }
+  \renewcommand{\bibfont}{\bibliofont}
+  \renewcommand\setcitestyle[1]{
+  \@for\@tempa:=#1\do
+  {\def\@tempb{round}\ifx\@tempa\@tempb
+     \renewcommand\NAT@open{(}\renewcommand\NAT@close{)}\fi
+   \def\@tempb{square}\ifx\@tempa\@tempb
+     \renewcommand\NAT@open{[}\renewcommand\NAT@close{]}\fi
+   \def\@tempb{angle}\ifx\@tempa\@tempb
+     \renewcommand\NAT@open{$<$}\renewcommand\NAT@close{$>$}\fi
+   \def\@tempb{curly}\ifx\@tempa\@tempb
+     \renewcommand\NAT@open{\{}\renewcommand\NAT@close{\}}\fi
+   \def\@tempb{semicolon}\ifx\@tempa\@tempb
+     \renewcommand\NAT@sep{;}\fi
+   \def\@tempb{colon}\ifx\@tempa\@tempb
+     \renewcommand\NAT@sep{;}\fi
+   \def\@tempb{comma}\ifx\@tempa\@tempb
+     \renewcommand\NAT@sep{,}\fi
+   \def\@tempb{authoryear}\ifx\@tempa\@tempb
+     \NAT@numbersfalse\fi
+   \def\@tempb{numbers}\ifx\@tempa\@tempb
+     \NAT@numberstrue\NAT@superfalse\fi
+   \def\@tempb{super}\ifx\@tempa\@tempb
+     \NAT@numberstrue\NAT@supertrue\fi
+   \def\@tempb{nobibstyle}\ifx\@tempa\@tempb
+     \let\bibstyle=\@gobble\fi
+   \def\@tempb{bibstyle}\ifx\@tempa\@tempb
+     \let\bibstyle=\@citestyle\fi
+   \def\@tempb{sort}\ifx\@tempa\@tempb
+     \def\NAT@sort{\@ne}\fi
+   \def\@tempb{nosort}\ifx\@tempa\@tempb
+     \def\NAT@sort{\z@}\fi
+   \def\@tempb{compress}\ifx\@tempa\@tempb
+     \def\NAT@cmprs{\@ne}\fi
+   \def\@tempb{nocompress}\ifx\@tempa\@tempb
+     \def\NAT@cmprs{\@z}\fi
+   \def\@tempb{sort&compress}\ifx\@tempa\@tempb
+     \def\NAT@sort{\@ne}\def\NAT@cmprs{\@ne}\fi
+   \def\@tempb{mcite}\ifx\@tempa\@tempb
+     \let\NAT@merge\@ne\fi
+   \def\@tempb{merge}\ifx\@tempa\@tempb
+     \@ifnum{\NAT@merge<\tw@}{\let\NAT@merge\tw@}{}\fi
+   \def\@tempb{elide}\ifx\@tempa\@tempb
+     \@ifnum{\NAT@merge<\thr@@}{\let\NAT@merge\thr@@}{}\fi
+   \def\@tempb{longnamesfirst}\ifx\@tempa\@tempb
+     \NAT@longnamestrue\fi
+   \def\@tempb{nonamebreak}\ifx\@tempa\@tempb
+     \def\NAT@nmfmt#1{\mbox{\NAT@up#1}}\fi
+   \expandafter\NAT@find@eq\@tempa=\relax\@nil
+   \if\@tempc\relax\else
+     \expandafter\NAT@rem@eq\@tempc
+     \def\@tempb{open}\ifx\@tempa\@tempb
+      \xdef\NAT@open{\@tempc}\fi
+     \def\@tempb{close}\ifx\@tempa\@tempb
+      \xdef\NAT@close{\@tempc}\fi
+     \def\@tempb{aysep}\ifx\@tempa\@tempb
+      \xdef\NAT@aysep{\@tempc}\fi
+     \def\@tempb{yysep}\ifx\@tempa\@tempb
+      \xdef\NAT@yrsep{\@tempc}\fi
+     \def\@tempb{notesep}\ifx\@tempa\@tempb
+      \xdef\NAT@cmt{\@tempc}\fi
+     \def\@tempb{citesep}\ifx\@tempa\@tempb
+      \xdef\NAT@sep{\@tempc}\fi
+   \fi
+  }%
+  \NAT@@setcites
+  }
+  \renewcommand\citestyle[1]{%
+    \ifcsname bibstyle@#1\endcsname%
+    \csname bibstyle@#1\endcsname\let\bibstyle\@gobble%
+    \else%
+    \@latex@error{Undefined `#1' citestyle}%
+    \fi
+  }%
+\fi
+\newcommand{\bibstyle@acmauthoryear}{%
+  \setcitestyle{%
+    authoryear,%
+    open={(},close={)},citesep={;},%
+    aysep={},yysep={,},%
+    notesep={, }}}
+\newcommand{\bibstyle@acmnumeric}{%
+  \setcitestyle{%
+    numbers,sort&compress,%
+    open={[},close={]},citesep={,},%
+    notesep={, }}}
+\citestyle{acmnumeric}
+\def\@startsection#1#2#3#4#5#6{%
+  \if@noskipsec \leavevmode \fi
+  \par
+  \@tempskipa #4\relax
+  \@afterindenttrue
+  \ifdim \@tempskipa <\z@
+    \@tempskipa -\@tempskipa \@afterindentfalse
+  \fi
+  \if@nobreak
+    \everypar{}%
+  \else
+    \addpenalty\@secpenalty\addvspace\@tempskipa
+  \fi
+  \@ifstar
+    {\@ssect{#3}{#4}{#5}{#6}}%
+    {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}
+\def\@sect#1#2#3#4#5#6[#7]#8{%
+  \ifnum #2>\c@secnumdepth
+    \let\@svsec\@empty
+  \else
+    \refstepcounter{#1}%
+    \protected@edef\@svsec{\@seccntformat{#1}\relax}%
+  \fi
+  \@tempskipa #5\relax
+  \ifdim \@tempskipa>\z@
+    \begingroup
+      #6{%
+        \@hangfrom{\hskip #3\relax\@svsec}%
+          \interlinepenalty \@M #8\@@par}%
+    \endgroup
+    \csname #1mark\endcsname{#7}%
+    \addcontentsline{toc}{#1}{%
+      \ifnum #2>\c@secnumdepth \else
+        \protect\numberline{\csname the#1\endcsname}%
+      \fi
+      #7}%
+  \else
+    \def\@svsechd{%
+      #6{\hskip #3\relax
+      \@svsec #8}%
+      \csname #1mark\endcsname{#7}%
+      \addcontentsline{toc}{#1}{%
+        \ifnum #2>\c@secnumdepth \else
+          \protect\numberline{\csname the#1\endcsname}%
+        \fi
+        #7}}%
+  \fi
+  \@xsect{#5}}
+\def\@xsect#1{%
+  \@tempskipa #1\relax
+  \ifdim \@tempskipa>\z@
+    \par \nobreak
+    \vskip \@tempskipa
+    \@afterheading
+  \else
+    \@nobreakfalse
+    \global\@noskipsectrue
+    \everypar{%
+      \if@noskipsec
+        \global\@noskipsecfalse
+       {\setbox\z@\lastbox}%
+        \clubpenalty\@M
+        \begingroup \@svsechd \endgroup
+        \unskip
+        \@tempskipa #1\relax
+        \hskip -\@tempskipa
+      \else
+        \clubpenalty \@clubpenalty
+        \everypar{}%
+      \fi}%
+  \fi
+  \ignorespaces}
+\def\@seccntformat#1{\csname the#1\endcsname\quad}
+\def\@ssect#1#2#3#4#5{%
+  \@tempskipa #3\relax
+  \ifdim \@tempskipa>\z@
+    \begingroup
+      #4{%
+        \@hangfrom{\hskip #1}%
+          \interlinepenalty \@M #5\@@par}%
+    \endgroup
+  \else
+    \def\@svsechd{#4{\hskip #1\relax #5}}%
+  \fi
+  \@xsect{#3}}
+\let\@footnotemark@nolink\@footnotemark
+\let\@footnotetext@nolink\@footnotetext
+\RequirePackage[bookmarksnumbered,breaklinks]{hyperref}
+\urlstyle{rm}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+\or % sigconf
+\or % siggraph
+\or % sigplan
+  \urlstyle{sf}
+\or % sigchi
+\or % sigchi-a
+  \urlstyle{sf}
+\fi
+\if@ACM@screen
+%  \hypersetup{colorlinks,
+%    linkcolor=ACMRed,
+%    citecolor=ACMPurple,
+%    urlcolor=ACMDarkBlue,
+%    filecolor=ACMDarkBlue}
+\else
+  \hypersetup{hidelinks}
+\fi
+\if@ACM@natbib
+  \let\citeN\cite
+  \let\cite\citep
+  \let\citeANP\citeauthor
+  \let\citeNN\citeyearpar
+  \let\citeyearNP\citeyear
+  \let\citeyear\citeyearpar
+  \let\citeNP\citealt
+  \def\shortcite#1{\citeyear{#1}}
+  \DeclareRobustCommand\citeA
+     {\begingroup\NAT@swafalse
+       \let\NAT@ctype\@ne\NAT@partrue\NAT@fullfalse\NAT@open\NAT@citetp}%
+  \providecommand\newblock{}%
+\else
+  \providecommand\citename[1]{#1}
+\fi
+\def\bibliographystyle#1{%
+  \ifx\@begindocumenthook\@undefined\else
+    \expandafter\AtBeginDocument
+  \fi
+    {\if@filesw
+       \immediate\write\@auxout{\string\bibstyle{#1}}%
+     \fi}}
+%\RequirePackage{graphicx, xcolor}
+%\definecolor[named]{ACMBlue}{cmyk}{1,0.1,0,0.1}
+%\definecolor[named]{ACMYellow}{cmyk}{0,0.16,1,0}
+%\definecolor[named]{ACMOrange}{cmyk}{0,0.42,1,0.01}
+%\definecolor[named]{ACMRed}{cmyk}{0,0.90,0.86,0}
+%\definecolor[named]{ACMLightBlue}{cmyk}{0.49,0.01,0,0}
+%\definecolor[named]{ACMGreen}{cmyk}{0.20,0,1,0.19}
+%\definecolor[named]{ACMPurple}{cmyk}{0.55,1,0,0.15}
+%\definecolor[named]{ACMDarkBlue}{cmyk}{1,0.58,0,0.21}
+\RequirePackage{geometry}
+\ifcase\ACM@format@nr
+\relax % manuscript
+   \geometry{letterpaper,head=1pc}%
+\or % acmsmall
+   \geometry{twoside=true,
+     includeheadfoot, head=1pc, foot=2pc,
+     paperwidth=6.75in, paperheight=10in,
+     top=58pt, bottom=44pt, inner=46pt, outer=46pt
+   }%
+\or % acmlarge
+   \geometry{twoside=true, head=1pc, foot=2pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot,
+     top=78pt, bottom=114pt, inner=81pt, outer=81pt
+     }%
+\or % acmtog
+   \geometry{twoside=true, head=1pc, foot=2pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot, columnsep=24pt,
+     top=52pt, bottom=75pt, inner=52pt, outer=52pt
+     }%
+\or % sigconf
+   \geometry{twoside=true, head=1pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot, columnsep=2pc,
+     top=57pt, bottom=73pt, inner=54pt, outer=54pt
+     }%
+\or % siggraph
+   \geometry{twoside=true, head=1pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot, columnsep=2pc,
+     top=57pt, bottom=73pt, inner=54pt, outer=54pt
+     }%
+\or % sigplan
+   \geometry{twoside=true, head=1pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot=false, columnsep=2pc,
+     top=1in, bottom=1in, inner=0.75in, outer=0.75in
+     }%
+\or % sigchi
+   \geometry{twoside=true, head=1pc,
+     paperwidth=8.5in, paperheight=11in,
+     includeheadfoot, columnsep=2pc,
+     top=66pt, bottom=73pt, inner=54pt, outer=54pt
+     }%
+\or % sigchi-a
+   \geometry{twoside=false, head=1pc,
+     paperwidth=11in, paperheight=8.5in,
+     includeheadfoot, marginparsep=72pt,
+     marginparwidth=170pt, columnsep=20pt,
+     top=72pt, bottom=72pt, left=314pt, right=72pt
+     }%
+     \@mparswitchfalse
+     \reversemarginpar
+\fi
+\setlength\parindent{10\p@}
+\setlength\parskip{\z@}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+  \setlength\parindent{9\p@}%
+\or % sigconf
+\or % siggraph
+\or % sigplan
+\or % sigchi
+\or % sigchi-a
+\fi
+\def\copyrightpermissionfootnoterule{\kern-3\p@
+  \hrule \@width \columnwidth \kern 2.6\p@}
+\RequirePackage{manyfoot}
+\SelectFootnoteRule[2]{copyrightpermission}
+\DeclareNewFootnote{copyrightpermission}
+\def\footnoterule{\kern-3\p@
+  \hrule \@width 4pc \kern 2.6\p@}
+\def\endminipage{%
+    \par
+    \unskip
+    \ifvoid\@mpfootins\else
+      \vskip\skip\@mpfootins
+      \normalcolor
+      \unvbox\@mpfootins
+    \fi
+    \@minipagefalse   %% added 24 May 89
+  \color@endgroup
+  \egroup
+  \expandafter\@iiiparbox\@mpargs{\unvbox\@tempboxa}}
+\def\@makefntext{\noindent\@makefnmark}
+\if@ACM@sigchiamode
+\long\def\@footnotetext#1{\marginpar{%
+    \reset@font\small
+    \interlinepenalty\interfootnotelinepenalty
+    \protected@edef\@currentlabel{%
+       \csname p@footnote\endcsname\@thefnmark
+    }%
+    \color@begingroup
+      \@makefntext{%
+        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \color@endgroup}}%
+\fi
+\long\def\@mpfootnotetext#1{%
+  \global\setbox\@mpfootins\vbox{%
+    \unvbox\@mpfootins
+    \reset@font\footnotesize
+    \hsize\columnwidth
+    \@parboxrestore
+    \protected@edef\@currentlabel
+         {\csname p@mpfootnote\endcsname\@thefnmark}%
+    \color@begingroup\centering
+      \@makefntext{%
+        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \color@endgroup}}
+\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}
+\newif\if@ACM@newfonts
+\@ACM@newfontstrue
+\IfFileExists{libertine.sty}{}{\ClassWarning{\@classname}{You do not
+    have libertine package installed.  Please upgrade your
+    TeX}\@ACM@newfontsfalse}
+\IfFileExists{zi4.sty}{}{\ClassWarning{\@classname}{You do not
+    have zi4 package installed.  Please upgrade your TeX}\@ACM@newfontsfalse}
+\IfFileExists{newtxmath.sty}{}{\ClassWarning{\@classname}{You do not
+    have newtxmath package installed.  Please upgrade your
+    TeX}\@ACM@newfontsfalse}
+\if@ACM@newfonts
+\RequirePackage[tt=false]{libertine}
+\RequirePackage[varqu]{zi4}
+\RequirePackage[libertine]{newtxmath}
+\else
+\RequirePackage{textcomp}
+\fi
+\if@ACM@sigchiamode
+  \renewcommand{\familydefault}{\sfdefault}
+\fi
+\RequirePackage{caption, float}
+\captionsetup[table]{position=top}
+\if@ACM@journal
+  \captionsetup{labelfont={sf, small},
+    textfont={sf, small},  margin=\z@}
+  \captionsetup[figure]{name={Fig.}}
+\else
+  \captionsetup{labelfont={bf},
+    textfont={bf}, labelsep=colon, margin=\z@}
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+  \or % acmsmall
+  \or % acmlarge
+  \or % acmtog
+  \or % sigconf
+  \or % siggraph
+    \captionsetup{textfont={it}}
+  \or % sigplan
+    \captionsetup{labelfont={bf},
+      textfont={normalfont}, labelsep=period, margin=\z@}
+  \or % sigchi
+    \captionsetup[figure]{labelfont={bf, small},
+      textfont={bf, small}}
+  \or % sigchi-a
+    \captionsetup[figure]{labelfont={bf, small},
+      textfont={bf, small}}
+  \fi
+\fi
+\newfloat{sidebar}{}{sbar}
+\floatname{sidebar}{Sidebar}
+\renewenvironment{sidebar}{\Collect@Body\@sidebar}{}
+\long\def\@sidebar#1{\bgroup\captionsetup{type=sidebar}%
+  \marginpar{\small#1}\egroup}
+\newenvironment{marginfigure}{\Collect@Body\@marginfigure}{}
+\long\def\@marginfigure#1{\bgroup\captionsetup{type=figure}%
+  \marginpar{\centering\small#1}\egroup}
+\newenvironment{margintable}{\Collect@Body\@margintable}{}
+\long\def\@margintable#1{\bgroup\captionsetup{type=table}%
+  \marginpar{\centering\small#1}\egroup}
+\newdimen\fulltextwidth
+\fulltextwidth=\dimexpr(\textwidth+\marginparwidth+\marginparsep)
+\if@ACM@sigchiamode
+\def\@dblfloat{\bgroup\columnwidth=\fulltextwidth
+  \let\@endfloatbox\@endwidefloatbox
+  \def\@fpsadddefault{\def\@fps{tp}}%
+  \@float}
+\fi
+\if@ACM@sigchiamode
+\def\end@dblfloat{%
+    \end@float\egroup}
+\fi
+\def\@endwidefloatbox{%
+  \par\vskip\z@skip
+  \@minipagefalse
+  \outer@nobreak
+  \egroup
+  \color@endbox
+  \global\setbox\@currbox=\vbox{\moveleft
+    \dimexpr(\fulltextwidth-\textwidth)\box\@currbox}%
+  \wd\@currbox=\textwidth
+}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+\or % sigconf
+\or % siggraph
+\or % sigplan
+\def\labelenumi{\theenumi.}
+\def\labelenumii{\theenumii.}
+\def\labelenumiii{\theenumiii.}
+\def\labelenumiv{\theenumiv.}
+\or % sigchi
+\or % sigchi-a
+\fi
+\renewcommand{\descriptionlabel}[1]{\hspace\labelsep \upshape\bfseries #1}
+\renewenvironment{description}{\list{}{%
+    \itemindent-12\p@
+    \labelwidth\z@ \let\makelabel\descriptionlabel}%
+}{
+  \endlist
+}
+\let\enddescription=\endlist % for efficiency
+\define@choicekey*+{ACM}{acmJournal}[\@journalCode\@journalCode@nr]{%
+  CIE,%
+  CSUR,%
+  IMWUT,%
+  JACM,%
+  JDIQ,%
+  JEA,%
+  JERIC,%
+  JETC,%
+  JOCCH,%
+  PACMPL,%
+  TAAS,%
+  TACCESS,%
+  TACO,%
+  TALG,%
+  TALLIP,%
+  TAP,%
+  TCPS,%
+  TEAC,%
+  TECS,%
+  TIIS,%
+  TISSEC,%
+  TIST,%
+  TKDD,%
+  TMIS,%
+  TOCE,%
+  TOCHI,%
+  TOCL,%
+  TOCS,%
+  TOCT,%
+  TODAES,%
+  TODS,%
+  TOG,%
+  TOIS,%
+  TOIT,%
+  TOMACS,%
+  TOMM,%
+  TOMPECS,%
+  TOMS,%
+  TOPC,%
+  TOPS,%
+  TOPLAS,%
+  TOS,%
+  TOSEM,%
+  TOSN,%
+  TRETS,%
+  TSAS,%
+  TSC,%
+  TSLP,%
+  TWEB%
+}{%
+\ifcase\@journalCode@nr
+\relax % CIE
+  \def\@journalName{ACM Computers in Entertainment}%
+  \def\@journalNameShort{ACM Comput. Entertain.}%
+  \def\@permissionCodeOne{1544-3574}%
+\or % CSUR
+  \def\@journalName{ACM Computing Surveys}%
+  \def\@journalNameShort{ACM Comput. Surv.}%
+  \def\@permissionCodeOne{0360-0300}%
+\or % IMWUT
+  \def\@journalName{PACM on Interactive, Mobile, Wearable and
+    Ubiquitous Technologies}%
+  \def\@journalNameShort{PACM Interact. Mob. Wearable Ubiquitous Technol.}%
+  \def\@permissionCodeOne{2474-9567}%
+\or % JACM
+  \def\@journalName{Journal of the ACM}%
+  \def\@journalNameShort{J. ACM}%
+  \def\@permissionCodeOne{0004-5411}%
+\or % JDIQ
+  \def\@journalName{ACM Journal of Data and Information Quality}%
+  \def\@journalNameShort{ACM J. Data Inform. Quality}%
+  \def\@permissionCodeOne{1936-1955}%
+\or % JEA
+  \def\@journalName{ACM Journal of Experimental Algorithmics}%
+  \def\@journalNameShort{ACM J. Exp. Algor.}%
+  \def\@permissionCodeOne{1084-6654}%
+\or % JERIC
+  \def\@journalName{ACM Journal of Educational Resources in Computing}%
+  \def\@journalNameShort{ACM J. Edu. Resources in Comput.}%
+  \def\@permissionCodeOne{1073-0516}%
+\or % JETC
+  \def\@journalName{ACM Journal on Emerging Technologies in Computing Systems}%
+  \def\@journalNameShort{ACM J. Emerg. Technol. Comput. Syst.}%
+  \def\@permissionCodeOne{1550-4832}%
+\or % JOCCH
+  \def\@journalName{ACM Journal on Computing and Cultural Heritage}%
+  \def\@journalName{ACM J. Comput. Cult. Herit.}%
+\or % PACMPL
+  \def\@journalName{PACM on Programming Languages}%
+  \def\@journalName{PACM Progr. Lang.}%
+  \def\@permissionCodeOne{2475-1421}%
+\or % TAAS
+  \def\@journalName{ACM Transactions on Autonomous and Adaptive Systems}%
+  \def\@journalNameShort{ACM Trans. Autonom. Adapt. Syst.}%
+  \def\@permissionCodeOne{1556-4665}%
+\or % TACCESS
+  \def\@journalName{ACM Transactions on Accessible Computing}%
+  \def\@journalNameShort{ACM Trans. Access. Comput.}%
+  \def\@permissionCodeOne{1936-7228}%
+\or % TACO
+  \def\@journalName{ACM Transactions on Architecture and Code Optimization}%
+\or % TALG
+  \def\@journalName{ACM Transactions on Algorithms}%
+  \def\@journalNameShort{ACM Trans. Algor.}%
+  \def\@permissionCodeOne{1549-6325}%
+\or % TALLIP
+  \def\@journalName{ACM Transactions on Asian and Low-Resource Language Information Processing}%
+  \def\@journalNameShort{ACM Trans. Asian Low-Resour. Lang. Inf. Process.}%
+  \def\@permissionCodeOne{2375-4699}%
+\or % TAP
+  \def\@journalName{ACM Transactions on Applied Perception}%
+\or % TCPS
+  \def\@journalName{ACM Transactions on Cyber-Physical Systems}%
+\or % TEAC
+  \def\@journalName{ACM Transactions on Economics and Computation}%
+\or % TECS
+  \def\@journalName{ACM Transactions on Embedded Computing Systems}%
+  \def\@journalNameShort{ACM Trans. Embedd. Comput. Syst.}%
+  \def\@permissionCodeOne{1539-9087}%
+\or % TIIS
+  \def\@journalName{ACM Transactions on Interactive Intelligent Systems}%
+  \def\@journalNameShort{ACM Trans. Interact. Intell. Syst.}%
+  \def\@permissionCodeOne{2160-6455}%
+\or % TISSEC
+  \def\@journalName{ACM Transactions on Information and System Security}%
+  \def\@journalNameShort{ACM Trans. Info. Syst. Sec.}%
+  \def\@permissionCodeOne{1094-9224}%
+\or % TIST
+  \def\@journalName{ACM Transactions on Intelligent Systems and Technology}%
+  \def\@journalNameShort{ACM Trans. Intell. Syst. Technol.}%
+  \def\@permissionCodeOne{2157-6904}%
+\or % TKDD
+  \def\@journalName{ACM Transactions on Knowledge Discovery from Data}%
+  \def\@journalNameShort{ACM Trans. Knowl. Discov. Data.}%
+  \def\@permissionCodeOne{1556-4681}%
+\or % TMIS
+  \def\@journalName{ACM Transactions on Management Information Systems}%
+  \def\@journalNameShort{ACM Trans. Manag. Inform. Syst.}%
+  \def\@permissionCodeOne{2158-656X}%
+\or % TOCE
+  \def\@journalName{ACM Transactions on Computing Education}%
+  \def\@journalNameShort{ACM Trans. Comput. Educ.}%
+  \def\@permissionCodeOne{1946-6226}%
+\or % TOCHI
+  \def\@journalName{ACM Transactions on Computer-Human Interaction}%
+  \def\@journalNameShort{ACM Trans. Comput.-Hum. Interact.}%
+  \def\@permissionCodeOne{1073-0516}%
+\or % TOCL
+  \def\@journalName{ACM Transactions on Computational Logic}%
+  \def\@journalNameShort{ACM Trans. Comput. Logic}%
+  \def\@permissionCodeOne{1529-3785}%
+\or % TOCS
+  \def\@journalName{ACM Transactions on Computer Systems}%
+  \def\@journalNameShort{ACM Trans. Comput. Syst.}%
+  \def\@permissionCodeOne{0734-2071}%
+\or % TOCT
+  \def\@journalName{ACM Transactions on Computation Theory}%
+  \def\@journalNameShort{ACM Trans. Comput. Theory}%
+  \def\@permissionCodeOne{1942-3454}%
+\or % TODAES
+  \def\@journalName{ACM Transactions on Design Automation of Electronic Systems}%
+  \def\@journalNameShort{ACM Trans. Des. Autom. Electron. Syst.}%
+  \def\@permissionCodeOne{1084-4309}%
+\or % TODS
+  \def\@journalName{ACM Transactions on Database Systems}%
+  \def\@journalNameShort{ACM Trans. Datab. Syst.}%
+  \def\@permissionCodeOne{0362-5915}%
+\or % TOG
+  \def\@journalName{ACM Transactions on Graphics}%
+  \def\@journalNameShort{ACM Trans. Graph.}%
+  \def\@permissionCodeOne{0730-0301}
+\or % TOIS
+  \def\@journalName{ACM Transactions on Information Systems}%
+  \def\@journalName{ACM Transactions on Information Systems}%
+  \def\@permissionCodeOne{1046-8188}%
+\or % TOIT
+  \def\@journalName{ACM Transactions on Internet Technology}%
+  \def\@journalNameShort{ACM Trans. Internet Technol.}%
+  \def\@permissionCodeOne{1533-5399}%
+\or % TOMACS
+  \def\@journalName{ACM Transactions on Modeling and Computer Simulation}%
+  \def\@journalName{ACM Transactions on Modeling and Computer Simulation}%
+  \def\@journalNameShort{ACM Trans. Model. Comput. Simul.}%
+\or % TOMM
+  \def\@journalName{ACM Transactions on Multimedia Computing, Communications and Applications}%
+  \def\@journalNameShort{ACM Trans. Multimedia Comput. Commun. Appl.}%
+  \def\@permissionCodeOne{1551-6857}%
+  \def\@permissionCodeTwo{0100}%
+\or % TOMPECS
+  \def\@journalName{ACM Transactions on Modeling and Performance Evaluation of Computing Systems}%
+  \def\@journalNameShort{ACM Trans. Model. Perform. Eval. Comput. Syst.}%
+  \def\@permissionCodeOne{2376-3639}%
+\or % TOMS
+  \def\@journalName{ACM Transactions on Mathematical Software}%
+  \def\@journalNameShort{ACM Trans. Math. Softw.}%
+  \def\@permissionCodeOne{0098-3500}%
+\or % TOPC
+  \def\@journalName{ACM Transactions on Parallel Computing}%
+  \def\@journalNameShort{ACM Trans. Parallel Comput.}%
+  \def\@permissionCodeOne{1539-9087}%
+\or % TOPS
+  \def\@journalName{ACM Transactions on Privacy and Security}%
+  \def\@journalNameShort{ACM Trans. Priv. Sec.}%
+  \def\@permissionCodeOne{2471-2566}%
+\or % TOPLAS
+  \def\@journalName{ACM Transactions on Programming Languages and Systems}%
+  \def\@journalNameShort{ACM Trans. Program. Lang. Syst.}%
+  \def\@permissionCodeOne{0164-0925}%
+\or % TOS
+  \def\@journalName{ACM Transactions on Storage}%
+  \def\@journalNameShort{ACM Trans. Storage}%
+  \def\@permissionCodeOne{1553-3077}%
+\or % TOSEM
+  \def\@journalName{ACM Transactions on Software Engineering and Methodology}%
+  \def\@journalNameShort{ACM Trans. Softw. Eng. Methodol.}%
+  \def\@permissionCodeOne{1049-331X}%
+\or % TOSN
+  \def\@journalName{ACM Transactions on Sensor Networks}%
+  \def\@journalNameShort{ACM Trans. Sensor Netw.}%
+  \def\@permissionCodeOne{1550-4859}%
+\or % TRETS
+  \def\@journalName{ACM Transactions on Reconfigurable Technology and Systems}%
+  \def\@journalNameShort{ACM Trans. Reconfig. Technol. Syst.}%
+  \def\@permissionCodeOne{1936-7406}%
+\or % TSAS
+  \def\@journalName{ACM Transactions on Spatial Algorithms and Systems}%
+  \def\@journalNameShort{ACM Trans. Spatial Algorithms Syst.}%
+  \def\@permissionCodeOne{2374-0353}%
+\or % TSC
+  \def\@journalName{ACM Transactions on Social Computing}%
+  \def\@journalNameShort{ACM Trans. Soc. Comput.}%
+  \def\@permissionCodeOne{2469-7818}%
+\or % TSLP
+  \def\@journalName{ACM Transactions on Speech and Language Processing}%
+  \def\@journalNameShort{ACM Trans. Speech Lang. Process.}%
+  \def\@permissionCodeOne{1550-4875}%
+\or % TWEB
+  \def\@journalName{ACM Transactions on the Web}%
+  \def\@journalNameShort{ACM Trans. Web}%
+  \def\@permissionCodeOne{1559-1131}%
+\fi
+\ClassInfo{\@classname}{Using journal code \@journalCode}%
+}{%
+  \ClassError{\@classname}{Incorrect journal #1}%
+}%
+\def\acmJournal#1{\setkeys{ACM}{acmJournal=#1}}
+\def\@journalCode@nr{0}
+\def\@journalName{}%
+\def\@journalNameShort{\@journalName}%
+\def\@permissionCodeOne{XXXX-XXXX}%
+\def\@permissionCodeTwo{}%
+\newcommand\acmConference[4][]{%
+  \gdef\acmConference@shortname{#1}%
+  \gdef\acmConference@name{#2}%
+  \gdef\acmConference@date{#3}%
+  \gdef\acmConference@venue{#4}%
+  \ifx\acmConference@shortname\@empty
+    \gdef\acmConference@shortname{#2}%
+  \fi}
+\acmConference[Conference'17]{ACM Conference}{July 2017}{Washington,
+  DC, USA}
+\def\subtitle#1{\def\@subtitle{#1}}
+\subtitle{}
+\newcount\num@authorgroups
+\num@authorgroups=0\relax
+\newif\if@insideauthorgroup
+\@insideauthorgroupfalse
+\renewcommand\author[2][]{%
+  \if@insideauthorgroup\else
+    \global\advance\num@authorgroups by 1\relax
+    \global\@insideauthorgrouptrue
+  \fi
+  \ifx\addresses\@empty
+    \if@ACM@anonymous
+      \gdef\addresses{\@author{Anonymous Author(s)}}%
+      \gdef\authors{Anonymous Author(s)}%
+    \else
+      \gdef\addresses{\@author{#2}}%
+      \gdef\authors{#2}%
+    \fi
+  \else
+    \if@ACM@anonymous\else
+      \g@addto@macro\addresses{\and\@author{#2}}%
+      \g@addto@macro\authors{\and#2}%
+    \fi
+  \fi
+  \if@ACM@anonymous
+    \ifx\shortauthors\@empty
+      \gdef\shortauthors{Anon.}%
+    \fi
+  \else
+    \def\@tempa{#1}%
+    \ifx\@tempa\@empty
+      \ifx\shortauthors\@empty
+        \gdef\shortauthors{#2}%
+      \else
+        \g@addto@macro\shortauthors{\and#2}%
+      \fi
+    \else
+      \ifx\shortauthors\@empty
+        \gdef\shortauthors{#1}%
+      \else
+        \g@addto@macro\shortauthors{\and#1}%
+      \fi
+    \fi
+  \fi}
+\newcommand{\affiliation}[2][]{%
+  \global\@insideauthorgroupfalse
+  \if@ACM@anonymous\else
+    \g@addto@macro\addresses{\affiliation{#1}{#2}}%
+  \fi}
+\renewcommand{\email}[2][]{%
+  \if@ACM@anonymous\else
+    \g@addto@macro\addresses{\email{#1}{#2}}%
+  \fi}
+\let\orcid\@gobble
+\def\@titlenotes{}
+\def\titlenote#1{%
+  \g@addto@macro\@title{\footnotemark}%
+  \if@ACM@anonymous
+    \g@addto@macro\@titlenotes{%
+      \stepcounter{footnote}\footnotetext{Title note}}%
+  \else
+    \g@addto@macro\@titlenotes{\stepcounter{footnote}\footnotetext{#1}}%
+  \fi}
+\def\@subtitlenotes{}
+\def\subtitlenote#1{%
+  \g@addto@macro\@subtitle{\footnotemark}%
+  \if@ACM@anonymous
+    \g@addto@macro\@subtitlenotes{%
+      \stepcounter{footnote}\footnotetext{Subtitle note}}%
+  \else
+    \g@addto@macro\@subtitlenotes{%
+      \stepcounter{footnote}\footnotetext{#1}}%
+  \fi}
+\def\@authornotes{}
+\def\authornote#1{%
+  \if@ACM@anonymous\else
+    \g@addto@macro\addresses{\@authornotemark}
+    \g@addto@macro\@authornotes{%
+      \stepcounter{footnote}\footnotetext{#1}}%
+  \fi}
+\def\acmVolume#1{\def\@acmVolume{#1}}
+\acmVolume{1}
+\def\acmNumber#1{\def\@acmNumber{#1}}
+\acmNumber{1}
+\def\acmArticle#1{\def\@acmArticle{#1}}
+\acmArticle{1}
+\def\acmArticleSeq#1{\def\@acmArticleSeq{#1}}
+\acmArticleSeq{\@acmArticle}
+\def\acmYear#1{\def\@acmYear{#1}}
+\acmYear{2016}
+\def\acmMonth#1{\def\@acmMonth{#1}}
+\acmMonth{1}
+\def\@acmPubDate{\ifcase\@acmMonth\or
+  January\or February\or March\or April\or May\or June\or
+  July\or August\or September\or October\or November\or
+  December\fi~\@acmYear}
+\def\acmPrice#1{\def\@acmPrice{#1}}
+\acmPrice{15.00}
+\def\acmISBN#1{\def\@acmISBN{#1}}
+\acmISBN{978-x-xxxx-xxxx-x/YY/MM}
+\def\acmDOI#1{\def\@acmDOI{#1}}
+\acmDOI{10.1145/nnnnnnn.nnnnnnn}
+\newif\if@ACM@badge
+\@ACM@badgefalse
+\newlength\@ACM@badge@width
+\setlength\@ACM@badge@width{5pc}
+\newlength\@ACM@title@width
+\newlength\@ACM@badge@skip
+\setlength\@ACM@badge@skip{1pc}
+\newcommand\acmBadgeR[2][]{\@ACM@badgetrue
+  \def\@acmBadgeR@url{#1}%
+  \def\@acmBadgeR@image{#2}}
+\def\@acmBadgeR@url{}
+\def\@acmBadgeR@image{}
+\newcommand\acmBadgeL[2][]{\@ACM@badgetrue
+  \def\@acmBadgeL@url{#1}%
+  \def\@acmBadgeL@image{#2}}
+\def\@acmBadgeL@url{}
+\def\@acmBadgeL@image{}
+\def\startPage#1{\def\@startPage{#1}}
+\startPage{}
+\def\terms#1{\def\@terms{#1}}
+\terms{}
+\def\keywords#1{\def\@keywords{#1}}
+\keywords{}
+\renewenvironment{abstract}{\Collect@Body\@saveabstract}{}
+\long\def\@saveabstract#1{\long\gdef\@abstract{#1}}
+\@saveabstract{}
+\long\def\@lempty{}
+\define@boolkey+{@ACM@topmatter@}[@ACM@]{printcss}[true]{%
+  \if@ACM@printcss
+    \ClassInfo{\@classname}{Printing CSS}%
+  \else
+    \ClassInfo{\@classname}{Suppressing CSS}%
+  \fi}{\ClassError{\@classname}{printcss must be true or false}}
+\define@boolkey+{@ACM@topmatter@}[@ACM@]{printacmref}[true]{%
+  \if@ACM@printacmref
+    \ClassInfo{\@classname}{Printing bibformat}%
+  \else
+    \ClassInfo{\@classname}{Suppressing bibformat}%
+  \fi}{\ClassError{\@classname}{printacmref must be true or false}}
+\define@boolkey+{@ACM@topmatter@}[@ACM@]{printfolios}[true]{%
+  \if@ACM@printfolios
+    \ClassInfo{\@classname}{Printing folios}%
+  \else
+    \ClassInfo{\@classname}{Suppressing folios}%
+  \fi}{\ClassError{\@classname}{printfolios must be true or false}}
+\def\settopmatter#1{\setkeys{@ACM@topmatter@}{#1}}
+\settopmatter{printcss=true, printacmref=true}
+\if@ACM@manuscript
+  \settopmatter{printfolios=true}
+\else
+  \if@ACM@journal
+    \settopmatter{printfolios=true}
+  \else
+    \settopmatter{printfolios=false}
+  \fi
+\fi
+\def\@received{}
+\newcommand\received[2][]{\def\@tempa{#1}%
+  \ifx\@tempa\@empty
+    \ifx\@received\@empty
+      \gdef\@received{Received #2}%
+    \else
+      \g@addto@macro{\@received}{; revised #2}%
+    \fi
+  \else
+    \ifx\@received\@empty
+      \gdef\@received{#1 #2}%
+    \else
+      \g@addto@macro{\@received}{; #1 #2}%
+    \fi
+  \fi}
+\AtEndDocument{%
+  \ifx\@received\@empty\else
+    \par\bigskip\noindent\small\normalfont\@received\par
+  \fi}
+\RequirePackage{comment}
+\excludecomment{CCSXML}
+\let\@concepts\@empty
+\newcommand\ccsdesc[2][100]{%
+  \ccsdesc@parse#1~#2~}
+\def\ccsdesc@parse#1~#2~#3~{%
+  \expandafter\ifx\csname CCS@#2\endcsname\relax
+    \expandafter\gdef\csname CCS@#2\endcsname{\textbullet\textbf{#2} $\to$ }%
+  \g@addto@macro{\@concepts}{\csname CCS@#2\endcsname}\fi
+  \expandafter\g@addto@macro\expandafter{\csname CCS@#2\endcsname}{%
+    \ifnum#1>499\textbf{#3; }\else
+    \ifnum#1>299\textit{#3; }\else
+    #3; \fi\fi}}
+\newif\if@printcopyright
+\@printcopyrighttrue
+\newif\if@printpermission
+\@printpermissiontrue
+\newif\if@acmowned
+\@acmownedtrue
+\define@choicekey*{ACM@}{acmcopyrightmode}[%
+  \acm@copyrightinput\acm@copyrightmode]{none,acmcopyright,acmlicensed,%
+  rightsretained,usgov,usgovmixed,cagov,cagovmixed,%
+  licensedusgovmixed,licensedcagovmixed,othergov,licensedothergov}{%
+  \@printpermissiontrue
+  \@printcopyrighttrue
+  \@acmownedtrue
+  \ifnum\acm@copyrightmode=0\relax % none
+   \@printpermissionfalse
+   \@printcopyrightfalse
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=2\relax % acmlicensed
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=3\relax % rightsretained
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=4\relax % usgov
+   \@printpermissiontrue
+   \@printcopyrightfalse
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=6\relax % cagov
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=8\relax % licensedusgovmixed
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=9\relax % licensedcagovmixed
+   \@acmownedfalse
+  \fi
+  \ifnum\acm@copyrightmode=10\relax % othergov
+   \@acmownedtrue
+  \fi
+  \ifnum\acm@copyrightmode=11\relax % licensedothergov
+   \@acmownedfalse
+  \fi}
+\def\setcopyright#1{\setkeys{ACM@}{acmcopyrightmode=#1}}
+\setcopyright{acmcopyright}
+\def\@copyrightowner{%
+  \ifcase\acm@copyrightmode\relax % none
+  \or % acmcopyright
+  ACM\@.
+  \or % acmlicensed
+  Copyright held by the owner/author(s). Publication rights licensed to
+  ACM\@.
+  \or % rightsretained
+  Copyright held by the owner/author(s).
+  \or % usgov
+  \or % usgovmixed
+  ACM\@.
+  \or % cagov
+  Crown in Right of Canada.
+  \or %cagovmixed
+  ACM\@.
+  \or %licensedusgovmixed
+  Copyright held by the owner/author(s). Publication rights licensed to
+  ACM\@.
+  \or %licensedcagovmixed
+  Copyright held by the owner/author(s). Publication rights licensed to
+  ACM\@.
+  \or % othergov
+  ACM\@.
+  \or % licensedothergov
+  Copyright held by the owner/author(s). Publication rights licensed to
+  ACM\@.
+  \fi}
+\def\@formatdoi#1{\url{http://dx.doi.org/#1}}
+\def\@copyrightpermission{%
+  \ifcase\acm@copyrightmode\relax % none
+  \or % acmcopyright
+   Permission to make digital or hard copies of all or part of this
+   work for personal or classroom use is granted without fee provided
+   that copies are not made or distributed for profit or commercial
+   advantage and that copies bear this notice and the full citation on
+   the first page. Copyrights for components of this work owned by
+   others than ACM must be honored. Abstracting with credit is
+   permitted. To copy otherwise, or republish, to post on servers or to
+   redistribute to lists, requires prior specific permission
+   and\hspace*{.5pt}/or  a fee. Request permissions from
+   permissions@acm.org.
+  \or % acmlicensed
+   Permission to make digital or hard copies of all or part of this
+   work for personal or classroom use is granted without fee provided
+   that copies are not made or distributed for profit or commercial
+   advantage and that copies bear this notice and the full citation on
+   the first page. Copyrights for components of this work owned by
+   others than the author(s) must be honored. Abstracting with credit
+   is permitted.  To copy otherwise, or republish, to post on servers
+   or to  redistribute to lists, requires prior specific permission
+   and\hspace*{.5pt}/or  a fee. Request permissions from
+   permissions@acm.org.
+  \or % rightsretained
+   Permission to make digital or hard copies of part or all of this work
+   for personal or classroom use is granted without fee provided that
+   copies are not made or distributed for profit or commercial advantage
+   and that copies bear this notice and the full citation on the first
+   page. Copyrights for third-party components of this work must be
+   honored. For all other uses, contact the
+   owner\hspace*{.5pt}/author(s).
+  \or % usgov
+   This paper is authored by an employee(s) of the United States
+   Government and is in the public domain. Non-exclusive copying or
+   redistribution is allowed, provided that the article citation is
+   given and the authors and agency are clearly identified as its
+   source.
+  \or % usgovmixed
+   ACM acknowledges that this contribution was authored or co-authored
+   by an employee, or contractor of the national government. As such,
+   the Government retains a nonexclusive, royalty-free right to
+   publish or reproduce this article, or to allow others to do so, for
+   Government purposes only. Permission to make digital or hard copies
+   for personal or classroom use is granted. Copies must bear this
+   notice and the full citation on the first page. Copyrights for
+   components of this work owned by others than ACM must be
+   honored. To copy otherwise, distribute, republish, or post,
+   requires prior specific permission and\hspace*{.5pt}/or a
+   fee. Request permissions from permissions@acm.org.
+  \or % cagov
+   This article was authored by employees of the Government of Canada.
+   As such, the Canadian government retains all interest in the
+   copyright to this work and grants to ACM a nonexclusive,
+   royalty-free right to publish or reproduce this article, or to allow
+   others to do so, provided that clear attribution is given both to
+   the authors and the Canadian government agency employing them.
+   Permission to make digital or hard copies for personal or classroom
+   use is granted. Copies must bear this notice and the full citation
+   on the first page.  Copyrights for components of this work owned by
+   others than the Canadain Government must be honored. To copy
+   otherwise, distribute, republish, or post, requires prior specific
+   permission and\hspace*{.5pt}/or a fee. Request permissions from
+   permissions@acm.org.
+  \or % cagovmixed
+   ACM acknowledges that this contribution was co-authored by an
+   affiliate of the national government of Canada. As such, the Crown
+   in Right of Canada retains an equal interest in the copyright.
+   Reprints must include clear attribution to ACM and the author's
+   government agency affiliation.  Permission to make digital or hard
+   copies for personal or classroom use is granted.  Copies must bear
+   this notice and the full citation on the first page. Copyrights for
+   components of this work owned by others than ACM must be honored.
+   To copy otherwise, distribute, republish, or post, requires prior
+   specific permission and\hspace*{.5pt}/or a fee. Request permissions
+   from permissions@acm.org.
+  \or % licensedusgovmixed
+   Publication rights licensed to ACM\@. ACM acknowledges that this
+   contribution was authored or co-authored by an employee, contractor
+   or affiliate of the United States government. As such, the
+   Government retains a nonexclusive, royalty-free right to publish or
+   reproduce this article, or to allow others to do so, for Government
+   purposes only.
+  \or % licensedcagovmixed
+   Publication rights licensed to ACM\@. ACM acknowledges that this
+   contribution was authored or co-authored by an employee, contractor
+   or affiliate of the national government of Canada. As such, the
+   Government retains a nonexclusive, royalty-free right to publish or
+   reproduce this article, or to allow others to do so, for Government
+   purposes only.
+  \or % othergov
+   ACM acknowledges that this contribution was authored or co-authored
+   by an employee, contractor or affiliate of a national government. As
+   such, the Government retains a nonexclusive, royalty-free right to
+   publish or reproduce this article, or to allow others to do so, for
+   Government purposes only.
+  \or % licensedothergov
+   Publication rights licensed to ACM\@. ACM acknowledges that this
+   contribution was authored or co-authored by an employee, contractor
+   or affiliate of a national government. As such, the Government
+   retains a nonexclusive, royalty-free right to publish or reproduce
+   this article, or to allow others to do so, for Government purposes
+   only.
+  \fi}
+\def\copyrightyear#1{\def\@copyrightyear{#1}}
+\copyrightyear{\@acmYear}
+\def\@teaserfigures{}
+\newenvironment{teaserfigure}{\Collect@Body\@saveteaser}{}
+\long\def\@saveteaser#1{\g@addto@macro\@teaserfigures{\@teaser{#1}}}
+\renewcommand{\thanks}[1]{%
+  \@ifnotempty{#1}{%
+    \if@ACM@anonymous
+      \g@addto@macro\thankses{\thanks{A note}}%
+   \else
+    \g@addto@macro\thankses{\thanks{#1}}%
+   \fi}}
+\newbox\mktitle@bx
+\def\maketitle{%
+  \if@ACM@anonymous
+    % Anonymize omission of \author-s
+    \ifnum\num@authorgroups=0\author{}\fi
+  \fi
+  \begingroup
+  \let\@footnotemark\@footnotemark@nolink
+  \let\@footnotetext\@footnotetext@nolink
+  \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+  \@topnum\z@ % this prevents figures from falling at the top of page
+              % 1
+  \hsize=\textwidth
+  \def\@makefnmark{\hbox{\@textsuperscript{\@thefnmark}}}%
+  \@mktitle\if@ACM@sigchiamode\else\@mkauthors\fi\@mkteasers
+  \@printtopmatter
+  \if@ACM@sigchiamode\@mkauthors\fi
+  \setcounter{footnote}{0}%
+  \def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}%
+  \@titlenotes
+  \@subtitlenotes
+  \@authornotes
+  \let\@makefnmark\relax  \let\@thefnmark\relax
+  \let\@makefntext\noindent
+  \ifx\@empty\thankses\else
+    \footnotetextcopyrightpermission{%
+      \def\par{\let\par\@par}\parindent\z@\@setthanks}%
+  \fi
+  \footnotetextcopyrightpermission{\parindent\z@\parskip0.1\baselineskip
+  \if@ACM@authorversion\else
+    \if@printpermission\@copyrightpermission\par\fi
+  \fi
+  \if@ACM@manuscript\else
+    \if@ACM@journal\else % Print the conference short name
+      {\itshape \acmConference@shortname, \acmConference@venue}\par
+    \fi
+  \fi
+  \if@printcopyright
+    \copyright\ \@copyrightyear\ \@copyrightowner\
+  \else
+    \@copyrightyear.\
+  \fi
+  \if@ACM@manuscript
+    Manuscript submitted to ACM\\
+  \else
+    \if@ACM@authorversion
+        This is the author's version of the work. It is posted here for
+        your personal use. Not for redistribution. The definitive Version
+        of Record was published in
+        \if@ACM@journal
+          \emph{\@journalName}%
+        \else
+          \emph{Proceedings of \acmConference@name, \acmConference@date}%
+        \fi
+        \ifx\@acmDOI\@empty
+        .
+        \else
+          , \@formatdoi{\@acmDOI}.
+        \fi\\
+      \else
+        \if@ACM@journal
+          \@permissionCodeOne/\@acmYear/\@acmMonth-ART\@acmArticle\
+          \$\@acmPrice\\
+          DOI: \nolinkurl{\@acmDOI}%
+        \else % Conference
+           \@acmISBN
+           \ifx\@acmPrice\@empty.\else\dots\$\@acmPrice\fi\\
+           DOI: \nolinkurl{\@acmDOI}%
+        \fi
+      \fi
+    \fi}%
+  \endgroup
+  \setcounter{footnote}{0}%
+  \@mkabstract
+  \if@ACM@printcss
+    \ifx\@concepts\@empty\else\bgroup
+      {\@specialsection{CCS Concepts}%
+         \@concepts\par}\egroup
+     \fi
+   \fi
+   \if\@terms\@empty\else\bgroup
+      {\@specialsection{General Terms}%
+         \@terms\par}\egroup
+   \fi
+   \ifx\@keywords\@empty\else\bgroup
+      {\if@ACM@journal
+         \@specialsection{Additional Key Words and Phrases}%
+       \else
+         \@specialsection{Keywords}%
+       \fi
+         \@keywords}\par\egroup
+   \fi
+  \andify\authors
+  \andify\shortauthors
+  \global\let\authors=\authors
+  \global\let\shortauthors=\shortauthors
+  \if@ACM@printacmref
+     \@mkbibcitation
+  \fi
+  \hypersetup{pdfauthor={\authors},
+    pdftitle={\@title}, pdfkeywords={\@concepts}}%
+  \@printendtopmatter
+  \@afterindentfalse
+  \@afterheading
+}
+\def\@specialsection#1{%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \par\medskip\small\noindent#1: %
+  \or % acmsmall
+    \par\medskip\small\noindent#1: %
+  \or % acmlarge
+    \par\medskip\small\noindent#1: %
+  \or % acmtog
+    \par\medskip\small\noindent#1: %
+  \or % sigconf
+    \section*{#1}%
+  \or % siggraph
+    \section*{#1}%
+  \or % sigplan
+    \paragraph*{#1}%
+  \or % sigchi
+    \section*{#1}%
+  \or % sigchi-a
+    \section*{#1}%
+  \fi}
+\def\@printtopmatter{%
+  \ifx\@startPage\@empty
+     \gdef\@startPage{1}%
+  \else
+     \setcounter{page}{\@startPage}%
+  \fi
+  \thispagestyle{firstpagestyle}%
+  \noindent
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \box\mktitle@bx\par
+    \noindent\hrulefill\par
+  \or % acmsmall
+    \box\mktitle@bx\par
+    \noindent\hrulefill\par
+  \or % acmlarge
+    \box\mktitle@bx\par
+    \noindent\hrulefill\par
+  \or % acmtog
+    \twocolumn[\box\mktitle@bx]%
+  \or % sigconf
+    \twocolumn[\box\mktitle@bx]%
+  \or % siggraph
+    \twocolumn[\box\mktitle@bx]%
+  \or % sigplan
+    \twocolumn[\box\mktitle@bx]%
+  \or % sigchi
+    \twocolumn[\box\mktitle@bx]%
+  \or % sigchi-a
+    \par\box\mktitle@bx\par\bigskip
+    \if@ACM@badge
+       \marginpar{\noindent
+         \ifx\@acmBadgeL@image\@empty\else
+           \href{\@acmBadgeL@url}{%
+             \includegraphics[width=\@ACM@badge@width]{\@acmBadgeL@image}}%
+            \hskip\@ACM@badge@skip
+          \fi
+         \ifx\@acmBadgeR@image\@empty\else
+           \href{\@acmBadgeR@url}{%
+             \includegraphics[width=\@ACM@badge@width]{\@acmBadgeR@image}}%
+          \fi}%
+    \fi
+  \fi
+}
+\def\@mktitle{%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \@mktitle@i
+  \or % acmsmall
+    \@mktitle@i
+  \or % acmlarge
+    \@mktitle@i
+  \or % acmtog
+    \@mktitle@i
+  \or % sigconf
+    \@mktitle@iii
+  \or % siggraph
+    \@mktitle@iii
+  \or % sigplan
+    \@mktitle@iii
+  \or % sigchi
+    \@mktitle@iii
+  \or % sigchi-a
+    \@mktitle@iv
+  \fi
+}
+\def\@titlefont{%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \LARGE\bfseries\sffamily
+  \or % acmsmall
+    \LARGE\bfseries\sffamily
+  \or % acmlarge
+    \LARGE\bfseries\sffamily
+  \or % acmtog
+    \Huge\sffamily
+  \or % sigconf
+    \Huge\sffamily\bfseries
+  \or % siggraph
+    \Huge\sffamily\bfseries
+  \or % sigplan
+    \Huge\bfseries
+  \or % sigchi
+    \Huge\sffamily\bfseries
+  \or % sigchi-a
+     \Huge\bfseries
+  \fi}
+\def\@subtitlefont{%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \mdseries
+  \or % acmsmall
+    \mdseries
+  \or % acmlarge
+    \mdseries
+  \or % acmtog
+     \LARGE
+  \or % sigconf
+     \LARGE\mdseries
+  \or % siggraph
+     \LARGE\mdseries
+  \or % sigplan
+     \LARGE\mdseries
+  \or % sigchi
+     \LARGE\mdseries
+  \or % sigchi-a
+     \mdseries
+  \fi}
+\def\@mktitle@i{\hsize=\textwidth
+  \@ACM@title@width=\hsize
+  \ifx\@acmBadgeL@image\@empty\else
+    \advance\@ACM@title@width by -\@ACM@badge@width
+    \advance\@ACM@title@width by -\@ACM@badge@skip
+  \fi
+  \ifx\@acmBadgeR@image\@empty\else
+    \advance\@ACM@title@width by -\@ACM@badge@width
+    \advance\@ACM@title@width by -\@ACM@badge@skip
+  \fi
+  \setbox\mktitle@bx=\vbox{\noindent\@titlefont
+    \ifx\@acmBadgeL@image\@empty\else
+      \raisebox{-.5\baselineskip}[\z@][\z@]{\href{\@acmBadgeL@url}{%
+          \includegraphics[width=\@ACM@badge@width]{\@acmBadgeL@image}}}%
+      \hskip\@ACM@badge@skip
+    \fi
+    \parbox[t]{\@ACM@title@width}{\raggedright
+      \@titlefont\noindent
+      \@title
+  \ifx\@subtitle\@empty\else
+    \par\noindent{\@subtitlefont\@subtitle}
+  \fi}%
+  \ifx\@acmBadgeR@image\@empty\else
+    \hskip\@ACM@badge@skip
+    \raisebox{-.5\baselineskip}[\z@][\z@]{\href{\@acmBadgeR@url}{%
+        \includegraphics[width=\@ACM@badge@width]{\@acmBadgeR@image}}}%
+  \fi
+  \par\bigskip}}%
+\def\@mktitle@iii{\hsize=\textwidth
+    \setbox\mktitle@bx=\vbox{\@titlefont\centering
+      \@ACM@title@width=\hsize
+      \if@ACM@badge
+        \advance\@ACM@title@width by -2\@ACM@badge@width
+        \advance\@ACM@title@width by -2\@ACM@badge@skip
+        \parbox[b]{\@ACM@badge@width}{\strut
+          \ifx\@acmBadgeL@image\@empty\else
+            \raisebox{-.5\baselineskip}[\z@][\z@]{\href{\@acmBadgeL@url}{%
+                \includegraphics[width=\@ACM@badge@width]{\@acmBadgeL@image}}}%
+          \fi}%
+        \hskip\@ACM@badge@skip
+      \fi
+      \parbox[t]{\@ACM@title@width}{\centering\@titlefont
+        \@title
+        \ifx\@subtitle\@empty\else
+          \par\noindent{\@subtitlefont\@subtitle}
+        \fi
+      }%
+      \if@ACM@badge
+        \hskip\@ACM@badge@skip
+        \parbox[b]{\@ACM@badge@width}{\strut
+          \ifx\@acmBadgeR@image\@empty\else
+            \raisebox{-.5\baselineskip}[\z@][\z@]{\href{\@acmBadgeR@url}{%
+                \includegraphics[width=\@ACM@badge@width]{\@acmBadgeR@image}}}%
+          \fi}%
+      \fi
+      \par\bigskip}}%
+\def\@mktitle@iv{\hsize=\textwidth
+    \setbox\mktitle@bx=\vbox{\raggedright\leftskip5pc\@titlefont
+      \noindent\leavevmode\leaders\hrule height 2pt\hfill\kern0pt\par
+      \noindent\@title
+     \ifx\@subtitle\@empty\else
+       \par\noindent\@subtitlefont\@subtitle
+     \fi
+     \par\bigskip}}%
+\newbox\@ACM@commabox
+\def\@ACM@addtoaddress#1{%
+  \ifvmode\else
+    \setbox\@ACM@commabox=\hbox{, }%
+    \unskip\cleaders\copy\@ACM@commabox\hskip\wd\@ACM@commabox
+  \fi
+  #1}
+\if@ACM@journal
+  \let\position\@gobble
+  \def\institution#1{#1\ignorespaces}%
+  \let\department\@gobble
+  \let\streetaddress\@gobble
+  \let\city\@gobble
+  \let\state\@gobble
+  \let\postcode\@gobble
+  \let\country\@gobble
+\else
+  \def\position#1{#1\par}%
+  \def\institution#1{#1\par}%
+  \def\department#1{#1\par}%
+  \def\streetaddress#1{#1\par}%
+  \let\city\@ACM@addtoaddress
+  \let\state\@ACM@addtoaddress
+  \def\postcode#1{\unskip\space#1}%
+  \let\country\@ACM@addtoaddress
+\fi
+\def\@mkauthors{\begingroup
+  \hsize=\textwidth
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \@mkauthors@i
+  \or % acmsmall
+    \@mkauthors@i
+  \or % acmlarge
+    \@mkauthors@i
+  \or % acmtog
+    \@mkauthors@i
+  \or % sigconf
+    \@mkauthors@iii
+  \or % siggraph
+    \@mkauthors@iii
+  \or % sigplan
+    \@mkauthors@iii
+  \or % sigchi
+    \@mkauthors@iii
+  \or % sigchi-a
+    \@mkauthors@iv
+  \fi
+  \endgroup
+}
+\def\@authorfont{\Large\sffamily}
+\def\@affiliationfont{\normalsize\normalfont}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+  \def\@authorfont{\large\sffamily}
+  \def\@affiliationfont{\small\normalfont}
+\or % acmlarge
+\or % acmtog
+  \def\@authorfont{\LARGE\sffamily}
+  \def\@affiliationfont{\large}
+\or % sigconf
+  \def\@authorfont{\LARGE}
+  \def\@affiliationfont{\large}
+\or % siggraph
+  \def\@authorfont{\normalsize\normalfont}
+  \def\@affiliationfont{\normalsize\normalfont}
+\or % sigplan
+  \def\@authorfont{\Large\normalfont}
+  \def\@affiliationfont{\normalsize\normalfont}
+\or % sigchi
+  \def\@authorfont{\bfseries}
+  \def\@affiliationfont{\mdseries}
+\or % sigchi-a
+  \def\@authorfont{\bfseries}
+  \def\@affiliationfont{\mdseries}
+\fi
+\def\@typeset@author@line{%
+  \andify\@currentauthors\par\noindent
+  \@currentauthors\def\@currentauthors{}%
+  \ifx\@currentaffiliations\@empty\else
+    \andify\@currentaffiliations
+      \unskip, {\@currentaffiliations}\par
+  \fi
+  \def\@currentaffiliations{}}
+\def\@mkauthors@i{%
+  \def\@currentauthors{}%
+  \def\@currentaffiliations{}%
+  \global\let\and\@typeset@author@line
+  \def\@author##1{%
+    \ifx\@currentauthors\@empty
+      \gdef\@currentauthors{\@authorfont\MakeUppercase{##1}}%
+    \else
+       \g@addto@macro{\@currentauthors}{\and\MakeUppercase{##1}}%
+    \fi
+    \gdef\and{}}%
+  \def\email##1##2{}%
+  \def\affiliation##1##2{%
+    \def\@tempa{##2}\ifx\@tempa\@empty\else
+       \ifx\@currentaffiliations\@empty
+          \gdef\@currentaffiliations{\@affiliationfont##2}%
+       \else
+         \g@addto@macro{\@currentaffiliations}{\and##2}%
+      \fi
+    \fi
+     \global\let\and\@typeset@author@line}
+  \global\setbox\mktitle@bx=\vbox{\noindent\box\mktitle@bx\par\medskip
+    \noindent\addresses\@typeset@author@line
+   \par\medskip}%
+}
+\newbox\author@bx
+\newdimen\author@bx@wd
+\newskip\author@bx@sep
+\author@bx@sep=1pc\relax
+\def\@typeset@author@bx{\bgroup\hsize=\author@bx@wd\def\and{\par}%
+  \global\setbox\author@bx=\vtop{\if@ACM@sigchiamode\else\centering\fi
+    \@authorfont\@currentauthors\par\@affiliationfont
+    \@currentaffiliation}\egroup
+  \box\author@bx\hspace{\author@bx@sep}%
+  \gdef\@currentauthors{}%
+  \gdef\@currentaffiliation{}}
+\def\@mkauthors@iii{%
+  \author@bx@wd=\textwidth\relax
+  \advance\author@bx@wd by -\author@bx@sep\relax
+  \ifcase\num@authorgroups
+  \relax % 0?
+  \or  % 1=one author per row
+  \or  % 2=two authors per row
+     \divide\author@bx@wd by \num@authorgroups\relax
+  \or  % 3=three authors per row
+     \divide\author@bx@wd by \num@authorgroups\relax
+  \or  % 4=two authors per row (!)
+     \divide\author@bx@wd by 2\relax
+  \else % three authors per row
+     \divide\author@bx@wd by 3\relax
+  \fi
+  \advance\author@bx@wd by -\author@bx@sep\relax
+  \gdef\@currentauthors{}%
+  \gdef\@currentaffiliation{}%
+  \def\@author##1{\ifx\@currentauthors\@empty
+    \gdef\@currentauthors{\par##1}%
+  \else
+    \g@addto@macro\@currentauthors{\par##1}%
+  \fi
+  \gdef\and{}}%
+  \def\email##1##2{\ifx\@currentaffiliation\@empty
+    \gdef\@currentaffiliation{\nolinkurl{##2}}%
+  \else
+    \g@addto@macro\@currentaffiliation{\par\nolinkurl{##2}}%
+  \fi}%
+  \def\affiliation##1##2{\ifx\@currentaffiliation\@empty
+    \gdef\@currentaffiliation{##2}%
+  \else
+    \g@addto@macro\@currentaffiliation{\par##2}%
+  \fi
+  \global\let\and\@typeset@author@bx
+}%
+  \hsize=\textwidth
+  \global\setbox\mktitle@bx=\vbox{\noindent
+    \box\mktitle@bx\par\medskip\leavevmode
+    \lineskip=1pc\relax\centering\hspace*{-1em}%
+    \addresses\let\and\@typeset@author@bx\and\par\bigskip}}
+\def\@mkauthors@iv{%
+  \author@bx@wd=\columnwidth\relax
+  \advance\author@bx@wd by -\author@bx@sep\relax
+  \ifcase\num@authorgroups
+  \relax % 0?
+  \or  % 1=one author per row
+  \else  % 2=two authors per row
+     \divide\author@bx@wd by 2\relax
+  \fi
+  \advance\author@bx@wd by -\author@bx@sep\relax
+  \gdef\@currentauthors{}%
+  \gdef\@currentaffiliation{}%
+  \def\@author##1{\ifx\@currentauthors\@empty
+    \gdef\@currentauthors{\par##1}%
+  \else
+    \g@addto@macro\@currentauthors{\par##1}%
+  \fi
+  \gdef\and{}}%
+  \def\email##1##2{\ifx\@currentaffiliation\@empty
+    \gdef\@currentaffiliation{\nolinkurl{##2}}%
+  \else
+    \g@addto@macro\@currentaffiliation{\par\nolinkurl{##2}}%
+  \fi}%
+  \def\affiliation##1##2{\ifx\@currentaffiliation\@empty
+    \gdef\@currentaffiliation{##2}%
+  \else
+    \g@addto@macro\@currentaffiliation{\par##2}%
+  \fi
+  \global\let\and\@typeset@author@bx}%
+    \bgroup\hsize=\columnwidth
+    \par\raggedright\leftskip=\z@
+    \lineskip=1pc\noindent
+    \addresses\let\and\@typeset@author@bx\and\par\bigskip\egroup}
+\def\@authornotemark{\g@addto@macro\@currentauthors{\footnotemark}}
+\def\@mkteasers{%
+  \ifx\@teaserfigures\@empty\else
+    \def\@teaser##1{\par\bigskip\bgroup
+      \captionsetup{type=figure}##1\egroup\par}
+    \global\setbox\mktitle@bx=\vbox{\noindent\box\mktitle@bx\par
+    \noindent\@teaserfigures\par\medskip}%
+  \fi}
+\def\@setaddresses{}
+\def\@mkabstract{\bgroup
+  \ifx\@abstract\@lempty\else
+  {\if@ACM@journal
+       \small\noindent
+    \else
+      \section*{Abstract}%
+    \fi
+   \phantomsection\addcontentsline{toc}{section}{Abstract}%
+   \ignorespaces\@abstract\par}%
+  \fi\egroup}
+\def\@mkbibcitation{\bgroup
+  \def\footnotemark{}%
+  \par\medskip\small\noindent{\bfseries ACM Reference format:}\par\nobreak
+  \noindent\authors. \@acmYear. \@title.
+  \if@ACM@journal
+     \textit{\@journalNameShort}
+     \@acmVolume, \@acmNumber, Article~\@acmArticle\ (\@acmPubDate),
+     \ref{TotPages}~pages.
+  \else
+     In \textit{Proceedings of \acmConference@name, \acmConference@venue,
+       \acmConference@date
+       \ifx\acmConference@name\acmConference@shortname\else
+         \ (\acmConference@shortname)\fi
+         ,} \ref{TotPages}~pages.
+  \fi\par
+  \noindent DOI: \nolinkurl{\@acmDOI}
+\par\egroup}
+\def\@printendtopmatter{\par\medskip
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \noindent\hrulefill\par\medskip
+  \or % acmsmall
+    \noindent\hrulefill\par\medskip
+  \or % acmlarge
+    \noindent\hrulefill\par\medskip
+  \or % acmtog
+    \par\bigskip
+  \or % sigconf
+    \par\bigskip
+  \or % siggraph
+    \par\bigskip
+  \or % sigplan
+    \par\bigskip
+  \or % sigchi
+    \par\bigskip
+  \or % sigchi-a
+  \fi
+}
+\def\@setthanks{\long\def\thanks##1{\par##1\@addpunct.}\thankses}
+\RequirePackage{fancyhdr}
+\if@ACM@review
+  \newsavebox{\ACM@linecount@bx}
+  \savebox{\ACM@linecount@bx}[4em][t]{\parbox[t]{4em}{%
+      \newlength\ACM@linecount@bxht\setlength{\ACM@linecount@bxht}{-\baselineskip}
+      \@tempcnta\@ne\relax
+%      \loop{\color{ACMRed}\scriptsize\the\@tempcnta}\\
+      \loop{\scriptsize\the\@tempcnta}\\
+      \advance\@tempcnta by \@ne
+      \addtolength{\ACM@linecount@bxht}{\baselineskip}
+      \ifdim\ACM@linecount@bxht<\textheight\repeat}}
+\fi
+\def\ACM@linecount{%
+  \if@ACM@review
+  \begin{picture}(0,0)%
+    \put(-26,-22){\usebox{\ACM@linecount@bx}}%
+  \end{picture}%
+  \fi}
+\def\@shortauthors{\if@ACM@anonymous Anon.\else\shortauthors\fi}
+\def\@headfootfont{%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \sffamily
+  \or % acmsmall
+    \sffamily
+  \or % acmlarge
+    \sffamily
+  \or % acmtog
+    \sffamily
+  \or % sigconf
+    \sffamily
+  \or % siggraph
+    \sffamily
+  \or % sigplan
+    \sffamily
+  \or % sigchi
+    \sffamily
+  \or % sigchi-a
+    \sffamily
+  \fi}
+\fancypagestyle{standardpagestyle}{%
+  \fancyhf{}%
+  \renewcommand{\headrulewidth}{\z@}%
+  \renewcommand{\footrulewidth}{\z@}%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \fancyhead[LE]{\ACM@linecount\if@ACM@printfolios\thepage\fi}%
+    \fancyhead[RO]{\if@ACM@printfolios\thepage\fi}%
+    \fancyhead[RE]{\@shortauthors}%
+    \fancyhead[LO]{\ACM@linecount\shorttitle}%
+    \fancyfoot[RO,LE]{\footnotesize Manuscript submitted to ACM}%
+  \or % acmsmall
+    \fancyhead[LE]{\ACM@linecount\@headfootfont\@acmArticle\if@ACM@printfolios:\thepage\fi}%
+    \fancyhead[RO]{\@headfootfont\@acmArticle\if@ACM@printfolios:\thepage\fi}%
+    \fancyhead[RE]{\@headfootfont\@shortauthors}%
+    \fancyhead[LO]{\ACM@linecount\@headfootfont\shorttitle}%
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date: \@acmPubDate.}%
+  \or % acmlarge
+    \fancyhead[LE]{\ACM@linecount\@headfootfont
+      \@acmArticle:\if@ACM@printfolios\thepage\quad\textbullet\quad\fi\@shortauthors}%
+    \fancyhead[LO]{\ACM@linecount}%
+    \fancyhead[RO]{\@headfootfont
+      \shorttitle\quad\textbullet\quad\@acmArticle\if@ACM@printfolios:\thepage\fi}%
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date: \@acmPubDate.}%
+  \or % acmtog
+    \fancyhead[LE]{\ACM@linecount\@headfootfont
+      \@acmArticle:\if@ACM@printfolios\thepage\quad\textbullet\quad\fi\@shortauthors}%
+    \fancyhead[LO]{\ACM@linecount}%
+    \fancyhead[RO]{\@headfootfont
+      \shorttitle\quad\textbullet\quad\@acmArticle\if@ACM@printfolios:\thepage\fi}%
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date: \@acmPubDate.}%
+  \else % Proceedings
+    \fancyfoot[C]{\if@ACM@printfolios\footnotesize\thepage\fi}%
+    \fancyhead[LO]{\ACM@linecount\@headfootfont\shorttitle}%
+    \fancyhead[RE]{\@headfootfont\@shortauthors}%
+    \fancyhead[LE]{\ACM@linecount\@headfootfont\acmConference@shortname,
+      \acmConference@date, \acmConference@venue}%
+    \fancyhead[RO]{\@headfootfont\acmConference@shortname,
+      \acmConference@date, \acmConference@venue}%
+  \fi
+  \if@ACM@sigchiamode
+     \fancyheadoffset[L]{\dimexpr(\marginparsep+\marginparwidth)}%
+  \fi
+}
+\pagestyle{standardpagestyle}
+\newdimen\@folio@wd
+\@folio@wd=\z@
+\newdimen\@folio@ht
+\@folio@ht=\z@
+\newdimen\@folio@voffset
+\@folio@voffset=\z@
+\def\@folio@max{1}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+  \@folio@wd=45.75pt\relax
+  \@folio@ht=1.25in\relax
+  \@folio@voffset=.2in\relax
+  \def\@folio@max{8}
+\or % acmlarge
+  \@folio@wd=43.25pt\relax
+  \@folio@ht=79pt\relax
+  \@folio@voffset=.55in\relax
+  \def\@folio@max{10}
+\fi
+\def\@folioblob{\@tempcnta=\@acmArticleSeq\relax
+  \loop
+     \ifnum\@tempcnta>\@folio@max\relax
+      \advance\@tempcnta by - \@folio@max
+   \repeat
+    \advance\@tempcnta by -1\relax
+    \@tempdima=\@folio@ht\relax
+    \multiply\@tempdima by \the\@tempcnta\relax
+    \advance\@tempdima by -\@folio@voffset\relax
+    \begin{picture}(0,0)
+    \makebox[\z@]{\raisebox{-\@tempdima}{%
+        \rlap{%
+          \raisebox{-0.45\@folio@ht}[\z@][\z@]{%
+            \rule{\@folio@wd}{\@folio@ht}}}%
+        \parbox{\@folio@wd}{%
+          \centering
+          \textcolor{white}{\LARGE\bfseries\sffamily\@acmArticle}}}}
+  \end{picture}}
+
+\fancypagestyle{firstpagestyle}{%
+  \fancyhf{}%
+  \renewcommand{\headrulewidth}{\z@}%
+  \renewcommand{\footrulewidth}{\z@}%
+  \ifcase\ACM@format@nr
+  \relax % manuscript
+    \fancyhead[L]{\ACM@linecount}%
+    \fancyfoot[RO,LE]{\if@ACM@printfolios\small\thepage\fi}%
+    \fancyfoot[RE,LO]{\footnotesize Manuscript submitted to ACM}%
+  \or % acmsmall
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date:
+    \@acmPubDate.}%
+    \fancyhead[LE]{\ACM@linecount\@folioblob}%
+    \fancyhead[LO]{\ACM@linecount}%
+    \fancyhead[RO]{\@folioblob}%
+    \fancyheadoffset[RO,LE]{0.6\@folio@wd}%
+  \or % acmlarge
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date:
+    \@acmPubDate.}%
+    \fancyhead[RO]{\@folioblob}%
+    \fancyhead[LE]{\ACM@linecount\@folioblob}%
+    \fancyhead[LO]{\ACM@linecount}%
+    \fancyheadoffset[RO,LE]{1.4\@folio@wd}%
+  \or % acmtog
+    \fancyfoot[RO,LE]{\footnotesize \@journalName, Vol. \@acmVolume, No.
+    \@acmNumber, Article \@acmArticle.  Publication date:
+    \@acmPubDate.}%
+    \fancyhead[L]{\ACM@linecount}%
+  \else % Conference proceedings
+    \fancyhead[L]{\ACM@linecount}%
+    \fancyfoot[C]{\if@ACM@printfolios\footnotesize\thepage\fi}%
+  \fi
+}
+\renewcommand\section{\@startsection{section}{1}{\z@}%
+  {-.75\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+  {.25\baselineskip}%
+  {\@secfont}}
+\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
+  {-.75\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+  {.25\baselineskip}%
+  {\@subsecfont}}
+\renewcommand\subsubsection{\@startsection{subsubsection}{3}{10pt}%
+  {-.5\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+  {-3.5\p@}%
+  {\@subsubsecfont\@adddotafter}}
+\renewcommand\paragraph{\@startsection{paragraph}{4}{\parindent}%
+  {-.5\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+  {-3.5\p@}%
+  {\@parfont\@adddotafter}}
+\renewcommand\part{\@startsection{part}{9}{\z@}%
+  {-10\p@ \@plus -4\p@ \@minus -2\p@}%
+  {4\p@}%
+  {\@parfont}}
+\def\section@raggedright{\@rightskip\@flushglue
+  \rightskip\@rightskip
+  \leftskip\z@skip
+  \parindent\z@}
+\def\@secfont{\sffamily\bfseries\section@raggedright\MakeUppercase}
+\def\@subsecfont{\sffamily\bfseries\section@raggedright}
+\def\@subsubsecfont{\sffamily\itshape}
+\def\@parfont{\itshape}
+\setcounter{secnumdepth}{3}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+ \def\@secfont{\sffamily\large\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\sffamily\large\section@raggedright}
+\or % acmtog
+ \def\@secfont{\sffamily\large\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\sffamily\large\section@raggedright}
+\or % sigconf
+ \def\@secfont{\bfseries\Large\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\bfseries\Large\section@raggedright}
+\or % siggraph
+ \def\@secfont{\bfseries\sffamily\Large\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\bfseries\sffamily\Large\section@raggedright}
+\or % sigplan
+ \def\@secfont{\bfseries\Large\section@raggedright}
+ \def\@subsecfont{\bfseries\section@raggedright}
+ \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
+   {-.75\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+   {.25\baselineskip}%
+   {\@subsubsecfont}}
+ \def\@subsubsecfont{\bfseries\section@raggedright}
+ \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
+   {-.5\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+   {-3.5\p@}%
+   {\@parfont\@addspaceafter}}
+ \def\@parfont{\bfseries\itshape}
+ \renewcommand\subparagraph{\@startsection{subparagraph}{5}{\z@}%
+   {-.5\baselineskip \@plus -2\p@ \@minus -.2\p@}%
+   {-3.5\p@}%
+   {\@subparfont\@addspaceafter}}
+ \def\@subparfont{\itshape}
+\or % sigchi
+ \setcounter{secnumdepth}{1}
+ \def\@secfont{\bfseries\sffamily\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\bfseries\sffamily\section@raggedright}
+\or % sigchi-a
+ \setcounter{secnumdepth}{0}
+ \def\@secfont{\bfseries\sffamily\section@raggedright\MakeUppercase}
+ \def\@subsecfont{\bfseries\sffamily\section@raggedright}
+\fi
+\def\@adddotafter#1{#1\@addpunct{.}}
+\def\@addspaceafter#1{#1\@addpunct{\enspace}}
+\def\@acmplainbodyfont{\itshape}
+\def\@acmplainindent{\parindent}
+\def\@acmplainheadfont{\scshape}
+\def\@acmplainnotefont{\@empty}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+\or % sigconf
+\or % siggraph
+\or % sigplan
+  \def\@acmplainbodyfont{\itshape}
+  \def\@acmplainindent{\z@}
+  \def\@acmplainheadfont{\bfseries}
+  \def\@acmplainnotefont{\normalfont}
+\or % sigchi
+\or % sigchi-a
+\fi
+\newtheoremstyle{acmplain}%
+  {.5\baselineskip\@plus.2\baselineskip
+    \@minus.2\baselineskip}% space above
+  {.5\baselineskip\@plus.2\baselineskip
+    \@minus.2\baselineskip}% space below
+  {\@acmplainbodyfont}% body font
+  {\@acmplainindent}% indent amount
+  {\@acmplainheadfont}% head font
+  {.}% punctuation after head
+  {.5em}% spacing after head
+  {\thmname{#1}\thmnumber{ #2}\thmnote{ {\@acmplainnotefont(#3)}}}% head spec
+\def\@acmdefinitionbodyfont{\normalfont}
+\def\@acmdefinitionindent{\parindent}
+\def\@acmdefinitionheadfont{\itshape}
+\def\@acmdefinitionnotefont{\@empty}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+\or % sigconf
+\or % siggraph
+\or % sigplan
+  \def\@acmdefinitionbodyfont{\normalfont}
+  \def\@acmdefinitionindent{\z@}
+  \def\@acmdefinitionheadfont{\bfseries}
+  \def\@acmdefinitionnotefont{\normalfont}
+\or % sigchi
+\or % sigchi-a
+\fi
+\newtheoremstyle{acmdefinition}%
+  {.5\baselineskip\@plus.2\baselineskip
+    \@minus.2\baselineskip}% space above
+  {.5\baselineskip\@plus.2\baselineskip
+    \@minus.2\baselineskip}% space below
+  {\@acmdefinitionbodyfont}% body font
+  {\@acmdefinitionindent}% indent amount
+  {\@acmdefinitionheadfont}% head font
+  {.}% punctuation after head
+  {.5em}% spacing after head
+  {\thmname{#1}\thmnumber{ #2}\thmnote{ {\@acmdefinitionnotefont(#3)}}}% head spec
+\theoremstyle{acmplain}
+\newtheorem{theorem}{Theorem}[section]
+\newtheorem{conjecture}[theorem]{Conjecture}
+\newtheorem{proposition}[theorem]{Proposition}
+\newtheorem{lemma}[theorem]{Lemma}
+\newtheorem{corollary}[theorem]{Corollary}
+\theoremstyle{acmdefinition}
+\newtheorem{example}[theorem]{Example}
+\newtheorem{definition}[theorem]{Definition}
+\theoremstyle{acmplain}
+\def\@proofnamefont{\scshape}
+\def\@proofindent{\indent}
+\ifcase\ACM@format@nr
+\relax % manuscript
+\or % acmsmall
+\or % acmlarge
+\or % acmtog
+\or % sigconf
+\or % siggraph
+\or % sigplan
+  \def\@proofnamefont{\itshape}
+  \def\@proofindent{\noindent}
+\or % sigchi
+\or % sigchi-a
+\fi
+\renewenvironment{proof}[1][\proofname]{\par
+  \pushQED{\qed}%
+  \normalfont \topsep6\p@\@plus6\p@\relax
+  \trivlist
+  \item[\@proofindent\hskip\labelsep
+        {\@proofnamefont #1\@addpunct{.}}]\ignorespaces
+}{%
+  \popQED\endtrivlist\@endpefalse
+}
+\specialcomment{acks}{%
+  \begingroup
+  \section*{Acknowledgments}
+  \phantomsection\addcontentsline{toc}{section}{Acknowledgments}
+}{%
+  \endgroup
+}
+\def\grantsponsor#1#2#3{#2}
+\newcommand\grantnum[3][]{#3%
+  \def\@tempa{#1}\ifx\@tempa\@empty\else\space(\url{#1})\fi}
+\if@ACM@screen
+  \includecomment{screenonly}
+  \excludecomment{printonly}
+\else
+  \excludecomment{screenonly}
+  \includecomment{printonly}
+\fi
+\if@ACM@anonymous
+  \excludecomment{anonsuppress}
+  \excludecomment{acks}
+\else
+  \includecomment{anonsuppress}
+\fi
+\newcommand\showeprint[2][arxiv]{%
+  \def\@tempa{#1}%
+  \ifx\@tempa\@empty\def\@tempa{arxiv}\fi
+  \def\@tempb{arxiv}%
+  \ifx\@tempa\@tempb
+     arXiv:\href{http://arxiv.org/abs/#2}{#2}\else arXiv:#2%
+  \fi}
+\normalsize\normalfont
+\endinput
+%%
+%% End of file `acmart.cls'.
Index: doc/papers/OOPSLA17/evaluation/.gitignore
===================================================================
--- doc/papers/OOPSLA17/evaluation/.gitignore	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/.gitignore	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,6 @@
+c-bench
+cpp-bench
+cpp-vbench
+cfa-bench
+*.o
+*.d
Index: doc/papers/OOPSLA17/evaluation/Makefile
===================================================================
--- doc/papers/OOPSLA17/evaluation/Makefile	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/Makefile	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,97 @@
+CC = gcc
+CFA = cfa
+DEPFLAGS = -MMD -MP
+CFLAGS = -O2
+ifdef N
+CFLAGS += -DN=$(N)
+endif
+CXXFLAGS = $(CFLAGS) --std=c++14
+MAKEFILE_NAME = ${firstword ${MAKEFILE_LIST}}
+
+.PHONY : all clean run-c run-cpp run-cfa run
+
+all : c-bench cpp-bench cpp-vbench cfa-bench
+
+# rewrite object generation to auto-determine deps
+COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS)
+COMPILE.cpp = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS)
+COMPILE.cfa = $(CFA) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS)
+
+c-%.o : c-%.c
+	$(COMPILE.c) $(OUTPUT_OPTION) -c $<
+
+cpp-%.o : cpp-%.cpp
+	$(COMPILE.cpp) $(OUTPUT_OPTION) -c $<
+
+cfa-%.o : cfa-%.c
+	$(COMPILE.cfa) $(OUTPUT_OPTION) -c $<
+
+COBJS = c-stack.o c-pair.o c-print.o c-bench.o
+CPPOBJS = cpp-bench.o
+CPPVOBJS = cpp-vstack.o cpp-vbench.o
+CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o cfa-bench.o
+
+${COBJS} ${CPPOBJS} ${CPPVOBJS} ${CFAOBJS} : ${MAKEFILE_NAME}
+
+CFILES = bench.h $(patsubst c-bench.h,,$(COBJS:.o=.h)) $(COBJS:.o=.c)
+CPPFILES = bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp $(CPPOBJS:.o=.cpp)
+CPPVFILES = bench.hpp object.hpp cpp-vprint.hpp $(patsubst cpp-vbench.hpp,,$(CPPVOBJS:.o=.hpp)) $(CPPVOBJS:.o=.cpp)
+CFAFILES = bench.h $(patsubst cfa-bench.h,,$(CFAOBJS:.o=.h)) $(CFAOBJS:.o=.c)
+
+c-bench : $(COBJS) c-bench.o
+	$(COMPILE.c) $(LDFLAGS) $^ -o $@
+
+cpp-bench : $(CPPOBJS) cpp-bench.o
+	$(COMPILE.cpp) $(LDFLAGS) $^ -o $@
+
+cpp-vbench : $(CPPVOBJS) cpp-vbench.o
+	$(COMPILE.cpp) $(LDFLAGS) $^ -o $@
+
+cfa-bench : $(CFAOBJS) cfa-bench.o
+	$(COMPILE.cfa) $(LDFLAGS) $^ -o $@
+
+# include dependency files
+-include $(COBJS:.o=.d)
+-include $(CPPOBJS:.o=.d)
+-include $(CPPVOBJS:.o=.d)
+-include $(CFAOBJS:.o=.d)
+
+clean :
+	rm -f $(COBJS) $(COBJS:.o=.d) c-bench
+	rm -f $(CPPOBJS) $(CPPOBJS:.o=.d) cpp-bench
+	rm -f $(CPPVOBJS) $(CPPVOBJS:.o=.d) cpp-vbench
+	rm -f $(CFAOBJS) $(CFAOBJS:.o=.d) cfa-bench
+
+run-c : c-bench
+	@echo
+	@echo '## C ##'
+	@/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$<
+	@printf 'source_size:\t%8d lines\n' `cat $(CFILES) | wc -l`
+	@printf 'redundant_type_annotations:%8d lines\n' `cat $(CFILES) | fgrep '/***/' -c`
+	@printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
+
+run-cpp : cpp-bench
+	@echo
+	@echo '## C++ ##'
+	@/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$<
+	@printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l`
+	@printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPFILES) | fgrep '/***/' -c`
+	@printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
+
+run-cppv : cpp-vbench
+	@echo
+	@echo '## C++obj ##'
+	@/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$<
+	@printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l`
+	@printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPVFILES) | fgrep '/***/' -c`
+	@printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
+
+run-cfa : cfa-bench
+	@echo
+	@echo '## Cforall ##'
+	@/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$<
+	@printf 'source_size:\t%8d lines\n' `cat $(CFAFILES) | wc -l`
+	@printf 'redundant_type_annotations:%8d lines\n' `cat $(CFAFILES) | fgrep '/***/' -c`
+	@printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
+
+run : run-c run-cfa run-cpp run-cppv
Index: doc/papers/OOPSLA17/evaluation/bench.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/bench.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/bench.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,15 @@
+#pragma once
+#include <stdio.h>
+#include <time.h>
+
+long ms_between(clock_t start, clock_t end) { return (end - start) / (CLOCKS_PER_SEC / 1000); }
+
+#define N 40000000
+#define TIMED(name, code) { \
+	volatile clock_t _start, _end; \
+	_start = clock(); \
+	code \
+	_end = clock(); \
+	printf("%s:\t%8ld ms\n", name, ms_between(_start, _end)); \
+}
+#define REPEAT_TIMED(name, n, code) TIMED( name, for (int _i = 0; _i < n; ++_i) { code } )
Index: doc/papers/OOPSLA17/evaluation/bench.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/bench.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/bench.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,17 @@
+#pragma once
+#include <iomanip>
+#include <iostream>
+#include <time.h>
+
+long ms_between(clock_t start, clock_t end) { return (end - start) / (CLOCKS_PER_SEC / 1000); }
+
+static const int N = 40000000;
+#define TIMED(name, code) { \
+	volatile clock_t _start, _end; \
+	_start = clock(); \
+	code \
+	_end = clock(); \
+	std::cout << name << ":\t" << std::setw(8) << ms_between(_start, _end) \
+		<< std::setw(0) << " ms" << std::endl; \
+}
+#define REPEAT_TIMED(name, n, code) TIMED( name, for (int _i = 0; _i < n; ++_i) { code } )
Index: doc/papers/OOPSLA17/evaluation/c-bench.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-bench.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-bench.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "bench.h"
+#include "c-pair.h"
+#include "c-stack.h"
+#include "c-print.h"
+
+_Bool* new_bool( _Bool b ) {
+	_Bool* q = malloc(sizeof(_Bool)); /***/
+	*q = b;
+	return q;
+}
+
+char* new_char( char c ) {
+	char* q = malloc(sizeof(char)); /***/
+	*q = c;
+	return q;
+}
+
+int* new_int( int i ) {
+	int* q = malloc(sizeof(int)); /***/
+	*q = i;
+	return q;
+}
+
+void* copy_bool( const void* p ) { return new_bool( *(const _Bool*)p ); } /***/
+void* copy_char( const void* p ) { return new_char( *(const char*)p ); } /***/
+void* copy_int( const void* p ) { return new_int( *(const int*)p ); } /***/
+void* copy_pair_bool_char( const void* p ) { return copy_pair( p, copy_bool, copy_char ); } /***/
+void free_pair_bool_char( void* p ) { free_pair( p, free, free ); } /***/
+
+int cmp_bool( const void* a, const void* b ) { /***/
+	return *(const _Bool*)a == *(const _Bool*)b ? 0 : *(const _Bool*)a < *(const _Bool*)b ? -1 : 1; 
+}
+
+int cmp_char( const void* a, const void* b ) { /***/
+	return *(const char*)a == *(const char*)b ? 0 : *(const char*)a < *(const char*)b ? -1 : 1;
+}
+
+int main(int argc, char** argv) {
+	FILE * out = fopen("/dev/null", "w");
+	int maxi = 0, vali = 42;
+	struct stack si = new_stack(), ti;
+
+	REPEAT_TIMED( "push_int", N, push_stack( &si, new_int( vali ) ); )
+	TIMED( "copy_int", 	copy_stack( &ti, &si, copy_int ); /***/ )
+	TIMED( "clear_int", clear_stack( &si, free ); /***/ )
+	REPEAT_TIMED( "pop_int", N, 
+		int* xi = pop_stack( &ti );
+		if ( *xi > maxi ) { maxi = *xi; }
+		free(xi); )
+	REPEAT_TIMED( "print_int", N/2, print( out, "dsds", vali, ":", vali, "\n" ); /***/ )
+
+	struct pair * maxp = new_pair( new_bool(0), new_char('\0') ),
+		* valp = new_pair( new_bool(1), new_char('a') );
+	struct stack sp = new_stack(), tp;
+
+	REPEAT_TIMED( "push_pair", N, push_stack( &sp, copy_pair_bool_char( valp ) ); )
+	TIMED( "copy_pair", copy_stack( &tp, &sp, copy_pair_bool_char ); /***/ )
+	TIMED( "clear_pair", clear_stack( &sp, free_pair_bool_char ); /***/ )
+	REPEAT_TIMED( "pop_pair", N, 
+		struct pair * xp = pop_stack( &tp );
+		if ( cmp_pair( xp, maxp, cmp_bool, cmp_char /***/ ) > 0 ) {
+			free_pair_bool_char( maxp ); /***/
+			maxp = xp;
+		} else {
+			free_pair_bool_char( xp ); /***/
+		} )
+	REPEAT_TIMED( "print_pair", N/2, print( out, "pbcspbcs", *valp, ":", *valp, "\n" ); /***/ )
+	free_pair_bool_char( maxp ); /***/
+	free_pair_bool_char( valp ); /***/
+	fclose(out);
+}
Index: doc/papers/OOPSLA17/evaluation/c-pair.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-pair.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-pair.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include "c-pair.h"
+
+struct pair* new_pair(void* first, void* second) {
+	struct pair* p = malloc(sizeof(struct pair)); /***/
+	*p = (struct pair){ first, second }; /***/
+	return p;
+}
+
+struct pair* copy_pair(const struct pair* src, 
+		void* (*copy_first)(const void*), void* (*copy_second)(const void*)) {
+	return new_pair( copy_first(src->first), copy_second(src->second) );
+}
+
+void free_pair(struct pair* p, void (*free_first)(void*), void (*free_second)(void*)) {
+	free_first(p->first);
+	free_second(p->second);
+	free(p);
+}
+
+int cmp_pair(const struct pair* a, const struct pair* b, 
+		int (*cmp_first)(const void*, const void*), int (*cmp_second)(const void*, const void*)) {
+	int c = cmp_first(a->first, b->first);
+	if ( c == 0 ) c = cmp_second(a->second, b->second);
+	return c;
+}
Index: doc/papers/OOPSLA17/evaluation/c-pair.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-pair.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-pair.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,16 @@
+#pragma once
+
+struct pair {
+	void* first;
+	void* second;
+};
+
+struct pair* new_pair(void* first, void* second);
+
+struct pair* copy_pair(const struct pair* src, 
+	void* (*copy_first)(const void*), void* (*copy_second)(const void*));
+
+void free_pair(struct pair* p, void (*free_first)(void*), void (*free_second)(void*));
+
+int cmp_pair(const struct pair* a, const struct pair* b, 
+	int (*cmp_first)(const void*, const void*), int (*cmp_second)(const void*, const void*));
Index: doc/papers/OOPSLA17/evaluation/c-print.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-print.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-print.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,47 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include "c-pair.h"
+#include "c-print.h"
+
+void print_string(FILE* out, const char* x) { fprintf(out, "%s", x); }
+
+void print_bool(FILE* out, _Bool x) { fprintf(out, "%s", x ? "true" : "false"); }
+
+void print_char(FILE* out, char x) {
+	if ( 0x20 <= x && x <= 0x7E ) { fprintf(out, "'%c'", x); }
+	else { fprintf(out, "'\\%x'", x); }
+}
+
+void print_int(FILE* out, int x) { fprintf(out, "%d", x); }
+
+void print_fmt(FILE* out, char fmt, void* p) {
+	switch( fmt ) {
+	case 's': print_string(out, (const char*)p); break; /***/
+	case 'b': print_bool(out, *(_Bool*)p); break; /***/
+	case 'c': print_char(out, *(char*)p); break; /***/
+	case 'd': print_int(out, *(int*)p); break; /***/
+	}
+}
+
+void print(FILE* out, const char* fmt, ...) {
+	va_list args;
+	va_start(args, fmt);
+	for (const char* it = fmt; *it; ++it) {
+		switch( *it ) {
+		case 's': print_string(out, va_arg(args, const char*)); break; /***/
+		case 'b': print_bool(out, va_arg(args, int)); break; /***/
+		case 'c': print_char(out, va_arg(args, int)); break; /***/
+		case 'd': print_int(out, va_arg(args, int)); break; /***/
+		case 'p': {
+			const struct pair x = va_arg(args, const struct pair); /***/
+			fprintf(out, "[");
+			print_fmt(out, *++it, x.first); /***/
+			fprintf(out, ", ");
+			print_fmt(out, *++it, x.second); /***/
+			fprintf(out, "]");
+			break;
+		}
+		}
+	}
+	va_end(args);
+}
Index: doc/papers/OOPSLA17/evaluation/c-print.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-print.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-print.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,9 @@
+#pragma once
+#include <stdio.h>
+
+void print_string(FILE* out, const char* x);
+void print_bool(FILE* out, _Bool x);
+void print_char(FILE* out, char x);
+void print_int(FILE* out, int x);
+
+void print(FILE* out, const char* fmt, ...);
Index: doc/papers/OOPSLA17/evaluation/c-stack.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-stack.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-stack.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include "c-stack.h"
+
+struct stack_node {
+	void* value;
+	struct stack_node* next;
+};
+
+struct stack new_stack() { return (struct stack){ NULL }; /***/ }
+
+void copy_stack(struct stack* s, const struct stack* t, void* (*copy)(const void*)) {
+	struct stack_node** crnt = &s->head;
+	for ( struct stack_node* next = t->head; next; next = next->next ) {
+		*crnt = malloc(sizeof(struct stack_node)); /***/
+		**crnt = (struct stack_node){ copy(next->value) }; /***/
+		crnt = &(*crnt)->next;
+	}
+	*crnt = 0;
+}
+
+void clear_stack(struct stack* s, void (*free_el)(void*)) {
+    for ( struct stack_node* next = s->head; next; ) {
+		struct stack_node* crnt = next;
+		next = crnt->next;
+		free_el(crnt->value);
+		free(crnt);
+	}
+	s->head = NULL;
+}
+
+_Bool stack_empty(const struct stack* s) { return s->head == NULL; }
+
+void push_stack(struct stack* s, void* value) {
+	struct stack_node* n = malloc(sizeof(struct stack_node)); /***/
+	*n = (struct stack_node){ value, s->head }; /***/
+	s->head = n;
+}
+
+void* pop_stack(struct stack* s) {
+	struct stack_node* n = s->head;
+	s->head = n->next;
+	void* x = n->value;
+	free(n);
+	return x;
+}
Index: doc/papers/OOPSLA17/evaluation/c-stack.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/c-stack.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/c-stack.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,14 @@
+#pragma once
+
+struct stack_node;
+struct stack {
+	struct stack_node* head;
+};
+
+struct stack new_stack();
+void copy_stack(struct stack* dst, const struct stack* src, void* (*copy)(const void*));
+void clear_stack(struct stack* s, void (*free_el)(void*));
+
+_Bool stack_empty(const struct stack* s);
+void push_stack(struct stack* s, void* value);
+void* pop_stack(struct stack* s);
Index: doc/papers/OOPSLA17/evaluation/cfa-bench.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-bench.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-bench.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include "bench.h"
+#include "cfa-stack.h"
+#include "cfa-pair.h"
+#include "cfa-print.h"
+
+int main( int argc, char *argv[] ) {
+	FILE * out = fopen( "/dev/null", "w" );
+	int maxi = 0, vali = 42;
+	stack(int) si, ti;
+
+	REPEAT_TIMED( "push_int", N, push( &si, vali ); )
+	TIMED( "copy_int", ti = si; )
+	TIMED( "clear_int", clear( &si ); )
+	REPEAT_TIMED( "pop_int", N, 
+		int xi = pop( &ti ); 
+		if ( xi > maxi ) { maxi = xi; } )
+	REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
+
+	pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
+	stack(pair(_Bool, char)) sp, tp;
+
+	REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
+	TIMED( "copy_pair", tp = sp; )
+	TIMED( "clear_pair", clear( &sp ); )
+	REPEAT_TIMED( "pop_pair", N, 
+		pair(_Bool, char) xp = pop( &tp ); 
+		if ( xp > maxp ) { maxp = xp; } )
+	REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
+	fclose(out);
+}
Index: doc/papers/OOPSLA17/evaluation/cfa-pair.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-pair.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-pair.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,35 @@
+#include "cfa-pair.h"
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); })
+int ?<?(pair(R, S) p, pair(R, S) q) {
+	return p.first < q.first || ( p.first == q.first && p.second < q.second );
+}
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); })
+int ?<=?(pair(R, S) p, pair(R, S) q) {
+	return p.first < q.first || ( p.first == q.first && p.second <= q.second );
+}
+
+forall(otype R, otype S | { int ?==?(R, R); int ?==?(S, S); })
+int ?==?(pair(R, S) p, pair(R, S) q) {
+	return p.first == q.first && p.second == q.second;
+}
+
+forall(otype R, otype S | { int ?!=?(R, R); int ?!=?(S, S); })
+int ?!=?(pair(R, S) p, pair(R, S) q) {
+	return p.first != q.first || p.second != q.second;
+}
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); })
+int ?>?(pair(R, S) p, pair(R, S) q) {
+	return p.first > q.first || ( p.first == q.first && p.second > q.second );
+}
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
+int ?>=?(pair(R, S) p, pair(R, S) q) {
+	return p.first > q.first || ( p.first == q.first && p.second >= q.second );
+}
Index: doc/papers/OOPSLA17/evaluation/cfa-pair.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-pair.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-pair.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,28 @@
+#pragma once
+
+forall(otype R, otype S) struct pair {
+	R first;
+	S second;
+};
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); })
+int ?<?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); })
+int ?<=?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S | { int ?==?(R, R); int ?==?(S, S); })
+int ?==?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S | { int ?!=?(R, R); int ?!=?(S, S); })
+int ?!=?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); })
+int ?>?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S 
+	| { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
+int ?>=?(pair(R, S) p, pair(R, S) q);
Index: doc/papers/OOPSLA17/evaluation/cfa-print.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-print.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-print.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include "cfa-pair.h"
+#include "cfa-print.h"
+
+forall(otype T, ttype Params | { void print(FILE*, T); void print(FILE*, Params); })
+void print(FILE* out, T arg, Params rest) {
+	print(out, arg);
+	print(out, rest);
+}
+
+void print(FILE* out, const char* x) { fprintf(out, "%s", x); }
+
+void print(FILE* out, _Bool x) { fprintf(out, "%s", x ? "true" : "false"); }
+
+void print(FILE* out, char x) {
+	if ( 0x20 <= x && x <= 0x7E ) { fprintf(out, "'%c'", x); }
+	else { fprintf(out, "'\\%x'", x); }
+}
+
+void print(FILE* out, int x) { fprintf(out, "%d", x); }
+
+forall(otype R, otype S | { void print(FILE*, R); void print(FILE*, S); })
+void print(FILE* out, pair(R, S) x) {
+	fprintf(out, "[");
+	print(out, x.first);
+	fprintf(out, ", ");
+	print(out, x.second);
+	fprintf(out, "]");
+}
Index: doc/papers/OOPSLA17/evaluation/cfa-print.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-print.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-print.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,14 @@
+#pragma once
+#include <stdio.h>
+#include "cfa-pair.h"
+
+forall(otype T, ttype Params | { void print(FILE*, T); void print(FILE*, Params); })
+void print(FILE* out, T arg, Params rest);
+
+void print(FILE* out, const char* x);
+void print(FILE* out, _Bool x);
+void print(FILE* out, char x);
+void print(FILE* out, int x);
+
+forall(otype R, otype S | { void print(FILE*, R); void print(FILE*, S); })
+void print(FILE* out, pair(R, S) x);
Index: doc/papers/OOPSLA17/evaluation/cfa-stack.c
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-stack.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-stack.c	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,52 @@
+#include <stdlib>
+#include "cfa-stack.h"
+
+forall(otype T) struct stack_node {
+	T value;
+	stack_node(T)* next;
+};
+
+forall(otype T) void ?{}(stack(T)* s) { (&s->head){ 0 }; }
+
+forall(otype T) void ?{}(stack(T)* s, stack(T) t) {
+	stack_node(T)** crnt = &s->head;
+	for ( stack_node(T)* next = t.head; next; next = next->next ) {
+		*crnt = ((stack_node(T)*)malloc()){ next->value }; /***/
+		stack_node(T)* acrnt = *crnt;
+		crnt = &acrnt->next;
+	}
+	*crnt = 0;
+}
+
+forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t) {
+	if ( s->head == t.head ) return *s;
+	clear(s);
+	s{ t };
+	return *s;
+}
+
+forall(otype T) void ^?{}(stack(T)* s) { clear(s); }
+
+forall(otype T) _Bool empty(const stack(T)* s) { return s->head == 0; }
+
+forall(otype T) void push(stack(T)* s, T value) {
+	s->head = ((stack_node(T)*)malloc()){ value, s->head }; /***/
+}
+
+forall(otype T) T pop(stack(T)* s) {
+	stack_node(T)* n = s->head;
+	s->head = n->next;
+	T x = n->value;
+	^n{};
+	free(n);
+	return x;
+}
+
+forall(otype T) void clear(stack(T)* s) {
+    for ( stack_node(T)* next = s->head; next; ) {
+		stack_node(T)* crnt = next;
+		next = crnt->next;
+		delete(crnt);
+	}
+	s->head = 0;
+}
Index: doc/papers/OOPSLA17/evaluation/cfa-stack.h
===================================================================
--- doc/papers/OOPSLA17/evaluation/cfa-stack.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cfa-stack.h	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,16 @@
+#pragma once
+
+forall(otype T) struct stack_node;
+forall(otype T) struct stack {
+	stack_node(T)* head;
+};
+
+forall(otype T) void ?{}(stack(T)* s);
+forall(otype T) void ?{}(stack(T)* s, stack(T) t);
+forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t);
+forall(otype T) void ^?{}(stack(T)* s);
+
+forall(otype T) _Bool empty(const stack(T)* s);
+forall(otype T) void push(stack(T)* s, T value);
+forall(otype T) T pop(stack(T)* s);
+forall(otype T) void clear(stack(T)* s);
Index: doc/papers/OOPSLA17/evaluation/cpp-bench.cpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-bench.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-bench.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,27 @@
+#include <algorithm>
+#include <fstream>
+#include "bench.hpp"
+#include "cpp-stack.hpp"
+#include "cpp-pair.hpp"
+#include "cpp-print.hpp"
+
+int main(int argc, char** argv) {
+	std::ofstream out{"/dev/null"};
+	int maxi = 0, vali = 42;
+	stack<int> si, ti;
+	
+	REPEAT_TIMED( "push_int", N, si.push( vali ); )
+	TIMED( "copy_int", ti = si; )
+	TIMED( "clear_int", si.clear(); )
+	REPEAT_TIMED( "pop_int", N, maxi = std::max( maxi, ti.pop() ); )
+	REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
+
+	pair<bool, char> maxp = { false, '\0' }, valp = { true, 'a' };
+	stack<pair<bool, char>> sp, tp;
+	
+	REPEAT_TIMED( "push_pair", N, sp.push( valp ); )
+	TIMED( "copy_pair", tp = sp; )
+	TIMED( "clear_pair", sp.clear(); )
+	REPEAT_TIMED( "pop_pair", N, maxp = std::max( maxp, tp.pop() ); )
+	REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
+}
Index: doc/papers/OOPSLA17/evaluation/cpp-pair.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-pair.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-pair.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,30 @@
+#pragma once
+#include <utility>
+
+template<typename R, typename S> struct pair {
+	R first;
+	S second;
+
+	pair() = default;
+	pair( R&& x, S&& y ) : first( std::move(x) ), second( std::move(y) ) {}
+
+	bool operator< (const pair<R, S>& o) const {
+		return first < o.first || ( first == o.first && second < o.second );
+	}
+
+	bool operator<= (const pair<R, S>& o) const {
+		return first < o.first || ( first == o.first && second <= o.second );
+	}
+
+	bool operator== (const pair<R, S>& o) const { return first == o.first && second == o.second; }
+
+	bool operator!= (const pair<R, S>& o) const { return first != o.first || second != o.second; }
+
+	bool operator> (const pair<R, S>& o) const {
+		return first > o.first || ( first == o.first && second > o.second );
+	}
+
+	bool operator>= (const pair<R, S>& o) const {
+		return first > o.first || ( first == o.first && second >= o.second );
+	}
+};
Index: doc/papers/OOPSLA17/evaluation/cpp-print.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-print.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-print.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,28 @@
+#pragma once
+#include <iomanip>
+#include <iostream>
+#include "cpp-pair.hpp"
+
+template<typename T> void print(std::ostream& out, const T& x) { out << x; }
+
+template<> void print<bool>(std::ostream& out, const bool& x) { out << (x ? "true" : "false"); }
+
+template<> void print<char>(std::ostream& out, const char& x ) {
+	if ( 0x20 <= x && x <= 0x7E ) { out << "'" << x << "'"; }
+	else { out << "'\\" << std::hex << (unsigned int)x << std::setbase(0) << "'"; }
+}
+
+template<typename R, typename S> 
+std::ostream& operator<< (std::ostream& out, const pair<R, S>& x) {
+	out << "[";
+	print(out, x.first);
+	out << ", ";
+	print(out, x.second);
+	return out << "]";
+}
+
+template<typename T, typename... Args> 
+void print(std::ostream& out, const T& arg, const Args&... rest) {
+	out << arg;
+	print(out, rest...);
+}
Index: doc/papers/OOPSLA17/evaluation/cpp-stack.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-stack.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-stack.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,61 @@
+#pragma once
+#include <utility>
+
+template<typename T> class stack {
+	struct node {
+		T value;
+		node* next;
+
+		node( const T& v, node* n = nullptr ) : value(v), next(n) {}
+	};
+	node* head;
+
+	void copy(const stack<T>& o) {
+		node** crnt = &head;
+		for ( node* next = o.head; next; next = next->next ) {
+			*crnt = new node{ next->value }; /***/
+			crnt = &(*crnt)->next;
+		}
+		*crnt = nullptr;
+	}
+public:
+	void clear() {
+	    for ( node* next = head; next; ) {
+			node* crnt = next;
+			next = crnt->next;
+			delete crnt;
+		}
+		head = nullptr;
+	}
+
+	stack() : head(nullptr) {}
+	stack(const stack<T>& o) { copy(o); }
+	stack(stack<T>&& o) : head(o.head) { o.head = nullptr; }
+	~stack() { clear(); }
+
+	stack& operator= (const stack<T>& o) {
+		if ( this == &o ) return *this;
+		clear();
+		copy(o);
+		return *this;
+	}
+
+	stack& operator= (stack<T>&& o) {
+		if ( this == &o ) return *this;
+		head = o.head;
+		o.head = nullptr;
+		return *this;
+	}
+
+	bool empty() const { return head == nullptr; }
+
+	void push(const T& value) { head = new node{ value, head };  /***/ }
+
+	T pop() {
+		node* n = head;
+		head = n->next;
+		T x = std::move(n->value);
+		delete n;
+		return x;
+	}
+};
Index: doc/papers/OOPSLA17/evaluation/cpp-vbench.cpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-vbench.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-vbench.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,30 @@
+#include <algorithm>
+#include <fstream>
+#include "bench.hpp"
+#include "cpp-vstack.hpp"
+#include "cpp-vprint.hpp"
+#include "object.hpp"
+
+int main(int argc, char** argv) {
+	std::ofstream out{"/dev/null"};
+	integer maxi{ 0 }, vali{ 42 };
+	stack si, ti;
+	
+	REPEAT_TIMED( "push_int", N, si.push( vali ); )
+	TIMED( "copy_int", ti = si; )
+	TIMED( "clear_int", si.clear(); )
+	REPEAT_TIMED( "pop_int", N, maxi = std::max( maxi, ti.pop()->as<integer>() ); /***/ )
+	REPEAT_TIMED( "print_int", N/2, print( out, vali, c_string{":"}, vali, c_string{"\n"} ); )
+
+	ptr<pair> maxp = make<pair>( make<boolean>(false), make<character>('\0') );
+	pair valp{ make<boolean>(true), make<character>('a') };
+	stack sp, tp;
+	
+	REPEAT_TIMED( "push_pair", N, sp.push( valp ); )
+	TIMED( "copy_pair", tp = sp; )
+	TIMED( "clear_pair", sp.clear(); )
+	REPEAT_TIMED( "pop_pair", N, 
+		ptr<pair> xp = as_ptr<pair>( tp.pop() ); /***/
+		if ( *xp > *maxp ) { maxp = std::move(xp); } )
+	REPEAT_TIMED( "print_pair", N/2, print( out, valp, c_string{":"}, valp, c_string{"\n"} ); )
+}
Index: doc/papers/OOPSLA17/evaluation/cpp-vprint.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-vprint.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-vprint.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,10 @@
+#pragma once
+#include <ostream>
+#include "object.hpp"
+
+void print(std::ostream& out, const printable& x) { x.print(out); }
+
+template<typename... Args> void print(std::ostream& out, const printable& x, const Args&... rest) {
+	x.print(out);
+	print(out, rest...);
+}
Index: doc/papers/OOPSLA17/evaluation/cpp-vstack.cpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-vstack.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-vstack.cpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,54 @@
+#include "cpp-vstack.hpp"
+#include <utility>
+
+stack::node::node( const object& v, node* n ) : value( v.new_copy() ), next( n ) {}
+
+void stack::copy(const stack& o) {
+	node** crnt = &head;
+	for ( node* next = o.head; next; next = next->next ) {
+		*crnt = new node{ *next->value };
+		crnt = &(*crnt)->next;
+	}
+	*crnt = nullptr;
+}
+
+stack::stack() : head(nullptr) {}
+stack::stack(const stack& o) { copy(o); }
+stack::stack(stack&& o) : head(o.head) { o.head = nullptr; }
+stack::~stack() { clear(); }
+
+stack& stack::operator= (const stack& o) {
+	if ( this == &o ) return *this;
+	clear();
+	copy(o);
+	return *this;
+}
+
+stack& stack::operator= (stack&& o) {
+	if ( this == &o ) return *this;
+	head = o.head;
+	o.head = nullptr;
+	return *this;
+}
+
+void stack::clear() {
+    for ( node* next = head; next; ) {
+		node* crnt = next;
+		next = crnt->next;
+		delete crnt;
+	}
+	head = nullptr;
+}
+
+
+bool stack::empty() const { return head == nullptr; }
+
+void stack::push(const object& value) { head = new node{ value, head }; /***/ }
+
+ptr<object> stack::pop() {
+	node* n = head;
+	head = n->next;
+	ptr<object> x = std::move(n->value);
+	delete n;
+	return x;
+}
Index: doc/papers/OOPSLA17/evaluation/cpp-vstack.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/cpp-vstack.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/cpp-vstack.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,26 @@
+#pragma once
+#include "object.hpp"
+
+class stack {
+	struct node {
+		ptr<object> value;
+		node* next;
+
+		node( const object& v, node* n = nullptr );
+	};
+	node* head;
+
+	void copy(const stack& o);
+public:
+	stack();
+	stack(const stack& o);
+	stack(stack&& o);
+	~stack();
+	stack& operator= (const stack& o);
+	stack& operator= (stack&& o);
+
+	void clear();
+	bool empty() const;
+	void push(const object& value);
+	ptr<object> pop();
+};
Index: doc/papers/OOPSLA17/evaluation/object.hpp
===================================================================
--- doc/papers/OOPSLA17/evaluation/object.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/object.hpp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,199 @@
+#pragma once
+#include <cstddef>
+#include <exception>
+#include <iomanip>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <typeinfo>
+#include <typeindex>
+
+class bad_cast : public std::exception {
+	std::string why;
+public:
+	bad_cast( const std::type_index& f, const std::type_index& t ) : std::exception() {
+		why = std::string{"bad cast of "} + f.name() + " to " + t.name();
+	}
+	~bad_cast() override = default;
+	
+	const char* what() const noexcept override { return why.c_str(); }
+};
+
+template<typename T> std::type_index class_of() { return { typeid(T) }; }
+
+template<typename T> using ptr = std::unique_ptr<T>;
+
+struct object {
+	std::type_index get_class() const { return { this ? typeid(*this) : typeid(std::nullptr_t) }; }
+
+	template<typename T> T& as() {
+		T* p = dynamic_cast<T*>(this);
+		if ( !p ) throw bad_cast{ get_class(), class_of<T>() };
+		return *p;
+	}
+
+	template<typename T> const T& as() const {
+		const T* p = dynamic_cast<const T*>(this);
+		if ( !p ) throw bad_cast{ get_class(), class_of<T>() };
+		return *p;
+	}
+
+	virtual ptr<object> new_inst() const = 0;
+	virtual ptr<object> new_copy() const = 0;
+	virtual object& operator= (const object&) = 0;
+	virtual ~object() = default;
+};
+
+template<typename T, typename... Args> static inline ptr<T> make(Args&&... args) {
+	return std::make_unique<T>(std::forward<Args>(args)...);
+}
+
+template<typename To, typename From> 
+ptr<To> as_ptr( ptr<From>&& p ) { return ptr<To>{ &p.release()->template as<To>() }; }
+
+struct ordered : public virtual object {
+	virtual int cmp(const ordered&) const = 0;
+
+	bool operator< (const ordered& that) const { return cmp(that) < 0; }
+	bool operator<= ( const ordered& that ) const { return cmp(that) <= 0; }
+	bool operator== ( const ordered& that ) const { return cmp(that) == 0; }
+	bool operator!= ( const ordered& that ) const { return cmp(that) != 0; }
+	bool operator> ( const ordered& that ) const { return cmp(that) > 0; }
+	bool operator>= ( const ordered& that ) const { return cmp(that) >= 0; }
+};
+
+struct printable : public virtual object {
+	virtual void print(std::ostream&) const = 0;
+};
+
+class boolean : public ordered, public printable {
+	bool x;
+public:
+	boolean() = default;
+	boolean(bool x) : x(x) {}
+	boolean(const boolean&) = default;
+	boolean(boolean&&) = default;
+	ptr<object> new_inst() const override { return make<boolean>(); }
+	ptr<object> new_copy() const override { return make<boolean>(*this); }
+	boolean& operator= (const boolean& that) {
+		x = that.x;
+		return *this;	
+	}
+	object& operator= (const object& that) override { return *this = that.as<boolean>(); } /***/
+	boolean& operator= (boolean&&) = default;
+	~boolean() override = default;
+
+	int cmp(const boolean& that) const { return x == that.x ? 0 : x == false ? -1 : 1; }
+	int cmp(const ordered& that) const override { return cmp( that.as<boolean>() ); } /***/
+
+	void print(std::ostream& out) const override { out << (x ? "true" : "false"); }
+};
+
+class character : public ordered, public printable {
+	char x;
+public:
+	character() = default;
+	character(char x) : x(x) {}
+	character(const character&) = default;
+	character(character&&) = default;
+	ptr<object> new_inst() const override { return make<character>(); }
+	ptr<object> new_copy() const override { return make<character>(*this); }
+	character& operator= (const character& that) {
+		x = that.x;
+		return *this;	
+	}
+	object& operator= (const object& that) override { return *this = that.as<character>(); } /***/
+	character& operator= (character&&) = default;
+	~character() override = default;
+
+	int cmp(const character& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; }
+	int cmp(const ordered& that) const override { return cmp( that.as<character>() ); } /***/
+
+	void print(std::ostream& out) const override {
+		if ( 0x20 <= x && x <= 0x7E ) { out << "'" << x << "'"; }
+		else { out << "'\\" << std::hex << (unsigned int)x << std::setbase(0) << "'"; }
+	}
+};
+
+class integer : public ordered, public printable {
+	int x;
+public:
+	integer() = default;
+	integer(int x) : x(x) {}
+	integer(const integer&) = default;
+	integer(integer&&) = default;
+	ptr<object> new_inst() const override { return make<integer>(); }
+	ptr<object> new_copy() const override { return make<integer>(*this); }
+	integer& operator= (const integer& that) {
+		x = that.x;
+		return *this;	
+	}
+	object& operator= (const object& that) override { return *this = that.as<integer>(); } /***/
+	integer& operator= (integer&&) = default;
+	~integer() override = default;
+
+	int cmp(const integer& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; }
+	int cmp(const ordered& that) const override { return cmp( that.as<integer>() ); } /***/
+
+	void print(std::ostream& out) const override { out << x; }
+};
+
+class c_string : public printable {
+	static constexpr const char* empty = "";
+	const char* s;
+public:
+	c_string() : s(empty) {}
+	c_string(const char* s) : s(s) {}
+	c_string(const c_string&) = default;
+	c_string(c_string&&) = default;
+	ptr<object> new_inst() const override { return make<c_string>(); }
+	ptr<object> new_copy() const override { return make<c_string>(s); }
+	c_string& operator= (const c_string& that) {
+		s = that.s;
+		return *this;
+	}
+	object& operator= (const object& that) override { return *this = that.as<c_string>(); } /***/
+	c_string& operator= (c_string&&) = default;
+	~c_string() override = default;
+
+	void print(std::ostream& out) const override { out << s; }
+};
+
+class pair : public ordered, public printable {
+	ptr<object> x;
+	ptr<object> y;
+public:
+	pair() = default;
+	pair(ptr<object>&& x, ptr<object>&& y) : x(std::move(x)), y(std::move(y)) {}
+	pair(const pair& that) : x(that.x->new_copy()), y(that.y->new_copy()) {}
+	pair(pair&& that) : x(std::move(that.x)), y(std::move(that.y)) {}
+	ptr<object> new_inst() const override { return make<pair>(); }
+	ptr<object> new_copy() const override { return make<pair>(x->new_copy(), y->new_copy()); }
+	pair& operator= (const pair& that) {
+		x = that.x->new_copy();
+		y = that.y->new_copy();
+		return *this;
+	}
+	object& operator= (const object& that) override { return *this = that.as<pair>(); } /***/
+	pair& operator= (pair&& that) {
+		x = std::move(that.x);
+		y = std::move(that.y);
+		return *this;
+	}
+	~pair() override = default;
+
+	int cmp(const pair& that) const {
+		int c = x->as<ordered>().cmp( that.x->as<ordered>() ); /***/
+		if ( c != 0 ) return c;
+		return y->as<ordered>().cmp( that.y->as<ordered>() ); /***/
+	}
+	int cmp(const ordered& that) const override { return cmp( that.as<pair>() ); }
+
+	void print(std::ostream& out) const override {
+		out << "[";
+		x->as<printable>().print(out); /***/
+		out << ", ";
+		y->as<printable>().print(out); /***/
+		out << "]";
+	}
+};
Index: doc/papers/OOPSLA17/evaluation/timing.dat
===================================================================
--- doc/papers/OOPSLA17/evaluation/timing.dat	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/timing.dat	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,11 @@
+"400 million repetitions"	"C"	"\\CFA{}"	"\\CC{}"	"\\CC{obj}"
+"push\nint"	3002	2459	1520	3305
+"copy\nint"	2985	2057	1521	3152
+"clear\nint"	1374	827	718	1469
+"pop\nint"	1416	1221	717	5467
+"print\nint"	5656	6758	3120	3121
+"push\npair"	4214	2752	946	6826
+"copy\npair"	6127	2105	993	7330
+"clear\npair"	2881	885	711	3564
+"pop\npair"	3046	5434	783	26538
+"print\npair"	7514	10714	8717	16525
Index: doc/papers/OOPSLA17/evaluation/timing.gp
===================================================================
--- doc/papers/OOPSLA17/evaluation/timing.gp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/evaluation/timing.gp	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,26 @@
+# set terminal pdfcairo linewidth 3 size 6,3
+# set output "timing.pdf"
+set terminal pslatex size 6.25,2.125 color solid
+set output "timing.tex"
+
+set pointsize 2.0
+set grid linetype 0
+set style data histogram
+set style histogram cluster gap 2
+set style fill solid border -1
+set offset -0.5,-0.35
+set boxwidth 0.8
+
+set key top left reverse Left
+
+set style fill solid noborder
+set linetype 1 lc rgb 'black'
+set linetype 2 lc rgb 'red'
+set linetype 3 lc rgb 'blue'
+set linetype 4 lc rgb 'green'
+
+SCALE=1000
+set ylabel "seconds"
+
+# set datafile separator ","
+plot for [COL=2:5] 'evaluation/timing.dat' using (column(COL)/SCALE):xticlabels(1) title columnheader
Index: doc/papers/OOPSLA17/generic_types.tex
===================================================================
--- doc/papers/OOPSLA17/generic_types.tex	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/generic_types.tex	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,1414 @@
+% take off review (for line numbers) and anonymous (for anonymization) on submission
+\documentclass[format=acmlarge,anonymous,review]{acmart}
+% \documentclass[format=acmlarge,review]{acmart}
+
+\usepackage{xspace,calc,comment}
+\usepackage{upquote}									% switch curled `'" to straight
+\usepackage{listings}									% format program code
+\usepackage{rotating}
+\usepackage[usenames]{color}
+
+\makeatletter
+% Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore
+% removes it as a variable-name character so keyworks in variables are highlighted
+\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
+
+% parindent is relative, i.e., toggled on/off in environments like itemize, so store the value for
+% use rather than use \parident directly.
+\newlength{\parindentlnth}
+\setlength{\parindentlnth}{\parindent}
+
+\newlength{\gcolumnposn}				% temporary hack because lstlisting does not handle tabs correctly
+\newlength{\columnposn}
+\setlength{\gcolumnposn}{2.75in}
+\setlength{\columnposn}{\gcolumnposn}
+\newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@commentstyle{#2}}}
+\newcommand{\CRT}{\global\columnposn=\gcolumnposn}
+
+% Latin abbreviation
+\newcommand{\abbrevFont}{\textit}	% set empty for no italics
+\newcommand*{\eg}{%
+	\@ifnextchar{,}{\abbrevFont{e}.\abbrevFont{g}.}%
+		{\@ifnextchar{:}{\abbrevFont{e}.\abbrevFont{g}.}%
+			{\abbrevFont{e}.\abbrevFont{g}.,\xspace}}%
+}%
+\newcommand*{\ie}{%
+	\@ifnextchar{,}{\abbrevFont{i}.\abbrevFont{e}.}%
+		{\@ifnextchar{:}{\abbrevFont{i}.\abbrevFont{e}.}%
+			{\abbrevFont{i}.\abbrevFont{e}.,\xspace}}%
+}%
+\newcommand*{\etc}{%
+	\@ifnextchar{.}{\abbrevFont{etc}}%
+        {\abbrevFont{etc}.\xspace}%
+}%
+\newcommand{\etal}{%
+	\@ifnextchar{.}{\abbrevFont{et~al}}%
+	        {\abbrevFont{et al}.\xspace}%
+}%
+\makeatother
+
+% Useful macros
+\newcommand{\CFAIcon}{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
+\newcommand{\CFA}{\protect\CFAIcon} % safe for section/caption
+\newcommand{\CC}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}\xspace} % C++ symbolic name
+\newcommand{\CCeleven}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}11\xspace} % C++11 symbolic name
+\newcommand{\CCfourteen}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}14\xspace} % C++14 symbolic name
+\newcommand{\CCseventeen}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}17\xspace} % C++17 symbolic name
+\newcommand{\CCtwenty}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}20\xspace} % C++20 symbolic name
+\newcommand{\CCV}{\rm C\kern-.1em\hbox{+\kern-.25em+}obj\xspace} % C++ virtual symbolic name
+\newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name
+\newcommand{\Textbf}[1]{{\color{red}\textbf{#1}}}
+\newcommand{\TODO}[1]{\textbf{TODO}: {\itshape #1}} % TODO included
+%\newcommand{\TODO}[1]{} % TODO elided
+
+% CFA programming language, based on ANSI C (with some gcc additions)
+\lstdefinelanguage{CFA}[ANSI]{C}{
+	morekeywords={_Alignas,_Alignof,__alignof,__alignof__,asm,__asm,__asm__,_At,_Atomic,__attribute,__attribute__,auto,
+		_Bool,catch,catchResume,choose,_Complex,__complex,__complex__,__const,__const__,disable,dtype,enable,__extension__,
+		fallthrough,fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,__label__,lvalue,_Noreturn,one_t,otype,restrict,_Static_assert,
+		_Thread_local,throw,throwResume,trait,try,ttype,typeof,__typeof,__typeof__,zero_t},
+}%
+
+\lstset{
+language=CFA,
+columns=fullflexible,
+basicstyle=\linespread{0.9}\sf,							% reduce line spacing and use sanserif font
+stringstyle=\tt,										% use typewriter font
+tabsize=4,												% 4 space tabbing
+xleftmargin=\parindentlnth,								% indent code to paragraph indentation
+%mathescape=true,										% LaTeX math escape in CFA code $...$
+escapechar=\$,											% LaTeX escape in CFA code
+keepspaces=true,										%
+showstringspaces=false,									% do not show spaces with cup
+showlines=true,											% show blank lines at end of code
+aboveskip=4pt,											% spacing above/below code block
+belowskip=3pt,
+% replace/adjust listing characters that look bad in sanserif
+literate={-}{\makebox[1.4ex][c]{\raisebox{0.5ex}{\rule{1.2ex}{0.06ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1
+	{~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
+	{<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1.4ex][c]{\raisebox{0.5ex}{\rule{1.2ex}{0.06ex}}}\kern-0.3ex\textgreater}2,
+moredelim=**[is][\color{red}]{`}{`},
+}% lstset
+
+% inline code @...@
+\lstMakeShortInline@%
+
+% ACM Information
+\citestyle{acmauthoryear}
+
+\acmJournal{PACMPL}
+
+\title{Generic and Tuple Types with Efficient Dynamic Layout in \protect\CFA}
+
+\author{Aaron Moss}
+\email{a3moss@uwaterloo.ca}
+\author{Robert Schluntz}
+\email{rschlunt@uwaterloo.ca}
+\author{Peter Buhr}
+\email{pabuhr@uwaterloo.ca}
+\affiliation{%
+	\institution{University of Waterloo}
+	\department{David R. Cheriton School of Computer Science}
+	\streetaddress{Davis Centre, University of Waterloo}
+	\city{Waterloo}
+	\state{ON}
+	\postcode{N2L 3G1}
+	\country{Canada}
+}
+
+\terms{generic, tuple, variadic, types}
+\keywords{generic types, tuple types, variadic types, polymorphic functions, C, Cforall}
+
+\begin{CCSXML}
+<ccs2012>
+<concept>
+<concept_id>10011007.10011006.10011008.10011024.10011025</concept_id>
+<concept_desc>Software and its engineering~Polymorphism</concept_desc>
+<concept_significance>500</concept_significance>
+</concept>
+<concept>
+<concept_id>10011007.10011006.10011008.10011024.10011028</concept_id>
+<concept_desc>Software and its engineering~Data types and structures</concept_desc>
+<concept_significance>500</concept_significance>
+</concept>
+<concept>
+<concept_id>10011007.10011006.10011041.10011047</concept_id>
+<concept_desc>Software and its engineering~Source code generation</concept_desc>
+<concept_significance>300</concept_significance>
+</concept>
+</ccs2012>
+\end{CCSXML}
+
+\ccsdesc[500]{Software and its engineering~Polymorphism}
+\ccsdesc[500]{Software and its engineering~Data types and structures}
+\ccsdesc[300]{Software and its engineering~Source code generation}
+
+\begin{abstract}
+The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects.
+This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
+Nonetheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive.
+The goal of the \CFA project is to create an extension of C that provides modern safety and productivity features while still ensuring strong backwards compatibility with C and its programmers.
+Prior projects have attempted similar goals but failed to honour C programming-style; for instance, adding object-oriented or functional programming with garbage collection is a non-starter for many C developers.
+Specifically, \CFA is designed to have an orthogonal feature-set based closely on the C programming paradigm, so that \CFA features can be added \emph{incrementally} to existing C code-bases, and C programmers can learn \CFA extensions on an as-needed basis, preserving investment in existing code and engineers.
+This paper describes two \CFA extensions, generic and tuple types, details how their design avoids shortcomings of similar features in C and other C-like languages, and presents experimental results validating the design.
+\end{abstract}
+
+\begin{document}
+\maketitle
+
+
+\section{Introduction and Background}
+
+The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects.
+This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
+The \citet{TIOBE} ranks the top 5 most popular programming languages as: Java 16\%, \Textbf{C 7\%}, \Textbf{\CC 5\%}, \Csharp 4\%, Python 4\% = 36\%, where the next 50 languages are less than 3\% each with a long tail.
+The top 3 rankings over the past 30 years are:
+\lstDeleteShortInline@%
+\begin{center}
+\setlength{\tabcolsep}{10pt}
+\begin{tabular}{@{}rccccccc@{}}
+		& 2017	& 2012	& 2007	& 2002	& 1997	& 1992	& 1987		\\ \hline
+Java	& 1		& 1		& 1		& 1		& 12	& -		& -			\\
+\Textbf{C}	& \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{1}& \Textbf{1}& \Textbf{1}	\\
+\CC		& 3		& 3		& 3		& 3		& 2		& 2		& 4			\\
+\end{tabular}
+\end{center}
+\lstMakeShortInline@%
+Love it or hate it, C is extremely popular, highly used, and one of the few systems languages.
+In many cases, \CC is often used solely as a better C.
+Nonetheless, C, first standardized over thirty years ago, lacks many features that make programming in more modern languages safer and more productive.
+
+\CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that aims to add modern language features to C while maintaining both source compatibility with C and a familiar programming model for programmers.
+The four key design goals for \CFA~\citep{Bilson03} are:
+(1) The behaviour of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler;
+(2) Standard C code must be as fast and as small when translated by a \CFA compiler as when translated by a C compiler;
+(3) \CFA code must be at least as portable as standard C code;
+(4) Extensions introduced by \CFA must be translated in the most efficient way possible.
+These goals ensure existing C code-bases can be converted to \CFA incrementally with minimal effort, and C programmers can productively generate \CFA code without training beyond the features being used.
+\CC is used similarly, but has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
+
+\CFA is currently implemented as a source-to-source translator from \CFA to the GCC-dialect of C~\citep{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by GCC, meeting goals (1)--(3).
+Ultimately, a compiler is necessary for advanced features and optimal performance.
+
+This paper identifies shortcomings in existing approaches to generic and variadic data types in C-like languages and presents a design for generic and variadic types avoiding those shortcomings.
+Specifically, the solution is both reusable and type-checked, as well as conforming to the design goals of \CFA with ergonomic use of existing C abstractions.
+The new constructs are empirically compared with both standard C and \CC; the results show the new design is comparable in performance.
+
+
+\subsection{Polymorphic Functions}
+\label{sec:poly-fns}
+
+\CFA{}\hspace{1pt}'s polymorphism was originally formalized by \citet{Ditchfield92}, and first implemented by \citet{Bilson03}.
+The signature feature of \CFA is parametric-polymorphic functions~\citep{forceone:impl,Cormack90,Duggan96} with functions generalized using a @forall@ clause (giving the language its name):
+\begin{lstlisting}
+`forall( otype T )` T identity( T val ) { return val; }
+int forty_two = identity( 42 );				$\C{// T is bound to int, forty\_two == 42}$
+\end{lstlisting}
+The @identity@ function above can be applied to any complete \emph{object type} (or @otype@).
+The type variable @T@ is transformed into a set of additional implicit parameters encoding sufficient information about @T@ to create and return a variable of that type.
+The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor and destructor.
+If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \emph{data type} (or @dtype@).
+
+In \CFA, the polymorphism runtime-cost is spread over each polymorphic call, due to passing more arguments to polymorphic functions;
+the experiments in Section~\ref{sec:eval} show this overhead is similar to \CC virtual-function calls.
+A design advantage is that, unlike \CC template-functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat.
+
+Since bare polymorphic-types provide a restricted set of available operations, \CFA provides a \emph{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable.
+For example, the function @twice@ can be defined using the \CFA syntax for operator overloading:
+\begin{lstlisting}
+forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x + x; }	$\C{// ? denotes operands}$
+int val = twice( twice( 3.7 ) );
+\end{lstlisting}
+which works for any type @T@ with a matching addition operator.
+The polymorphism is achieved by creating a wrapper function for calling @+@ with @T@ bound to @double@, then passing this function to the first call of @twice@.
+There is now the option of using the same @twice@ and converting the result to @int@ on assignment, or creating another @twice@ with type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada}, in its type analysis.
+The first approach has a late conversion from @double@ to @int@ on the final assignment, while the second has an eager conversion to @int@.
+\CFA minimizes the number of conversions and their potential to lose information, so it selects the first approach, which corresponds with C-programmer intuition.
+
+Crucial to the design of a new programming language are the libraries to access thousands of external software features.
+Like \CC, \CFA inherits a massive compatible library-base, where other programming languages must rewrite or provide fragile inter-language communication with C.
+A simple example is leveraging the existing type-unsafe (@void *@) C @bsearch@ to binary search a sorted floating-point array:
+\begin{lstlisting}
+void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
+				int (* compar)( const void *, const void * ));
+int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
+				*(double *)t2 < *(double *)t1 ? 1 : 0; }
+double key = 5.0, vals[10] = { /* 10 sorted floating-point values */ };
+double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );	$\C{// search sorted array}$
+\end{lstlisting}
+which can be augmented simply with a generalized, type-safe, \CFA-overloaded wrappers:
+\begin{lstlisting}
+forall( otype T | { int ?<?( T, T ); } ) T * bsearch( T key, const T * arr, size_t size ) {
+	int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ }
+	return (T *)bsearch( &key, arr, size, sizeof(T), comp ); }
+forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
+	T * result = bsearch( key, arr, size );	$\C{// call first version}$
+	return result ? result - arr : size; }	$\C{// pointer subtraction includes sizeof(T)}$
+double * val = bsearch( 5.0, vals, 10 );	$\C{// selection based on return type}$
+int posn = bsearch( 5.0, vals, 10 );
+\end{lstlisting}
+The nested function @comp@ provides the hidden interface from typed \CFA to untyped (@void *@) C, plus the cast of the result.
+Providing a hidden @comp@ function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope.
+As well, an alternate kind of return is made available: position versus pointer to found element.
+\CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a templated @bsearch@.
+
+\CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations.
+For example, it is possible to write a type-safe \CFA wrapper @malloc@ based on the C @malloc@:
+\begin{lstlisting}
+forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
+int * ip = malloc();						$\C{// select type and size from left-hand side}$
+double * dp = malloc();
+struct S {...} * sp = malloc();
+\end{lstlisting}
+where the return type supplies the type/size of the allocation, which is impossible in most type systems.
+
+Call-site inferencing and nested functions provide a localized form of inheritance.
+For example, the \CFA @qsort@ only sorts in ascending order using @<@.
+However, it is trivial to locally change this behaviour:
+\begin{lstlisting}
+forall( otype T | { int ?<?( T, T ); } ) void qsort( const T * arr, size_t size ) { /* use C qsort */ }
+{	int ?<?( double x, double y ) { return x `>` y; }	$\C{// locally override behaviour}$
+	qsort( vals, size );					$\C{// descending sort}$
+}
+\end{lstlisting}
+Within the block, the nested version of @<@ performs @>@ and this local version overrides the built-in @<@ so it is passed to @qsort@.
+Hence, programmers can easily form local environments, adding and modifying appropriate functions, to maximize reuse of other existing functions and types.
+
+Finally, \CFA allows variable overloading:
+\begin{lstlisting}
+short int MAX = ...;   int MAX = ...;  double MAX = ...;
+short int s = MAX;    int i = MAX;    double d = MAX;   $\C{// select correct MAX}$
+\end{lstlisting}
+Here, the single name @MAX@ replaces all the C type-specific names: @SHRT_MAX@, @INT_MAX@, @DBL_MAX@.
+As well, restricted constant overloading is allowed for the values @0@ and @1@, which have special status in C, \eg the value @0@ is both an integer and a pointer literal, so its meaning depends on context.
+In addition, several operations are defined in terms values @0@ and @1@, \eg:
+\begin{lstlisting}
+int x;
+if (x) x++									$\C{// if (x != 0) x += 1;}$
+\end{lstlisting}
+Every @if@ and iteration statement in C compares the condition with @0@, and every increment and decrement operator is semantically equivalent to adding or subtracting the value @1@ and storing the result.
+Due to these rewrite rules, the values @0@ and @1@ have the types @zero_t@ and @one_t@ in \CFA, which allows overloading various operations for new types that seamlessly connect to all special @0@ and @1@ contexts.
+The types @zero_t@ and @one_t@ have special built in implicit conversions to the various integral types, and a conversion to pointer types for @0@, which allows standard C code involving @0@ and @1@ to work as normal.
+
+
+\subsection{Traits}
+
+\CFA provides \emph{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration:
+\begin{lstlisting}
+trait summable( otype T ) {
+	void ?{}( T *, zero_t );				$\C{// constructor from 0 literal}$
+	T ?+?( T, T );							$\C{// assortment of additions}$
+	T ?+=?( T *, T );
+	T ++?( T * );
+	T ?++( T * ); };
+forall( otype T `| summable( T )` ) T sum( T a[$\,$], size_t size ) {  // use trait
+	`T` total = { `0` };					$\C{// instantiate T from 0 by calling its constructor}$
+	for ( unsigned int i = 0; i < size; i += 1 ) total `+=` a[i]; $\C{// select appropriate +}$
+	return total; }
+\end{lstlisting}
+
+In fact, the set of @summable@ trait operators is incomplete, as it is missing assignment for type @T@, but @otype@ is syntactic sugar for the following implicit trait:
+\begin{lstlisting}
+trait otype( dtype T | sized(T) ) {  // sized is a pseudo-trait for types with known size and alignment
+	void ?{}( T * );						$\C{// default constructor}$
+	void ?{}( T *, T );						$\C{// copy constructor}$
+	void ?=?( T *, T );						$\C{// assignment operator}$
+	void ^?{}( T * ); };					$\C{// destructor}$
+\end{lstlisting}
+Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack-allocatable, default or copy-initialized, assigned, and deleted.
+
+In summation, the \CFA type-system uses \emph{nominal typing} for concrete types, matching with the C type-system, and \emph{structural typing} for polymorphic types.
+Hence, trait names play no part in type equivalence;
+the names are simply macros for a list of polymorphic assertions, which are expanded at usage sites.
+Nevertheless, trait names form a logical subtype-hierarchy with @dtype@ at the top, where traits often contain overlapping assertions, \eg operator @+@.
+Traits are used like interfaces in Java or abstract base-classes in \CC, but without the nominal inheritance-relationships.
+Instead, each polymorphic function (or generic type) defines the structural type needed for its execution (polymorphic type-key), and this key is fulfilled at each call site from the lexical environment, which is similar to Go~\citep{Go} interfaces.
+Hence, new lexical scopes and nested functions are used extensively to create local subtypes, as in the @qsort@ example, without having to manage a nominal-inheritance hierarchy.
+(Nominal inheritance can be approximated with traits using marker variables or functions, as is done in Go.)
+
+% Nominal inheritance can be simulated with traits using marker variables or functions:
+% \begin{lstlisting}
+% trait nominal(otype T) {
+%     T is_nominal;
+% };
+% int is_nominal;								$\C{// int now satisfies the nominal trait}$
+% \end{lstlisting}
+%
+% Traits, however, are significantly more powerful than nominal-inheritance interfaces; most notably, traits may be used to declare a relationship \emph{among} multiple types, a property that may be difficult or impossible to represent in nominal-inheritance type systems:
+% \begin{lstlisting}
+% trait pointer_like(otype Ptr, otype El) {
+%     lvalue El *?(Ptr);						$\C{// Ptr can be dereferenced into a modifiable value of type El}$
+% }
+% struct list {
+%     int value;
+%     list * next;								$\C{// may omit "struct" on type names as in \CC}$
+% };
+% typedef list * list_iterator;
+%
+% lvalue int *?( list_iterator it ) { return it->value; }
+% \end{lstlisting}
+% In the example above, @(list_iterator, int)@ satisfies @pointer_like@ by the user-defined dereference function, and @(list_iterator, list)@ also satisfies @pointer_like@ by the built-in dereference operator for pointers. Given a declaration @list_iterator it@, @*it@ can be either an @int@ or a @list@, with the meaning disambiguated by context (\eg @int x = *it;@ interprets @*it@ as an @int@, while @(*it).value = 42;@ interprets @*it@ as a @list@).
+% While a nominal-inheritance system with associated types could model one of those two relationships by making @El@ an associated type of @Ptr@ in the @pointer_like@ implementation, few such systems could model both relationships simultaneously.
+
+
+\section{Generic Types}
+
+One of the known shortcomings of standard C is that it does not provide reusable type-safe abstractions for generic data structures and algorithms.
+Broadly speaking, there are three approaches to implement abstract data-structures in C.
+One approach is to write bespoke data-structures for each context in which they are needed.
+While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures.
+A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@; an approach which does allow reuse of code for common functionality.
+However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that would not otherwise be needed.
+A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type-checked, but errors may be difficult to interpret.
+Furthermore, writing and using preprocessor macros can be unnatural and inflexible.
+
+\CC, Java, and other languages use \emph{generic types} to produce type-safe abstract data-types.
+\CFA also implements generic types that integrate efficiently and naturally with the existing polymorphic functions, while retaining backwards compatibility with C and providing separate compilation.
+However, for known concrete parameters, the generic-type definition can be inlined, like \CC templates.
+
+A generic type can be declared by placing a @forall@ specifier on a @struct@ or @union@ declaration, and instantiated using a parenthesized list of types after the type name:
+\begin{lstlisting}
+forall( otype R, otype S ) struct pair {
+	R first;
+	S second;
+};
+forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
+forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; }
+pair( const char *, int ) p = { "magic", 42 };
+int magic = value( p );
+pair( void *, int * ) q = { 0, &p.second };
+magic = value_p( q );
+double d = 1.0;
+pair( double *, double * ) r = { &d, &d };
+d = value_p( r );
+\end{lstlisting}
+
+\CFA classifies generic types as either \emph{concrete} or \emph{dynamic}.
+Concrete types have a fixed memory layout regardless of type parameters, while dynamic types vary in memory layout depending on their type parameters.
+A type may have polymorphic parameters but still be concrete, called \emph{dtype-static}.
+Polymorphic pointers are an example of dtype-static types, \eg @forall(dtype T) T *@ is a polymorphic type, but for any @T@, @T *@  is a fixed-sized pointer, and therefore, can be represented by a @void *@ in code generation.
+
+\CFA generic types also allow checked argument-constraints.
+For example, the following declaration of a sorted set-type ensures the set key supports equality and relational comparison:
+\begin{lstlisting}
+forall( otype Key | { _Bool ?==?(Key, Key); _Bool ?<?(Key, Key); } ) struct sorted_set;
+\end{lstlisting}
+
+
+\subsection{Concrete Generic-Types}
+
+The \CFA translator template-expands concrete generic-types into new structure types, affording maximal inlining.
+To enable inter-operation among equivalent instantiations of a generic type, the translator saves the set of instantiations currently in scope and reuses the generated structure declarations where appropriate.
+A function declaration that accepts or returns a concrete generic-type produces a declaration for the instantiated structure in the same scope, which all callers may reuse.
+For example, the concrete instantiation for @pair( const char *, int )@ is:
+\begin{lstlisting}
+struct _pair_conc1 {
+	const char * first;
+	int second;
+};
+\end{lstlisting}
+
+A concrete generic-type with dtype-static parameters is also expanded to a structure type, but this type is used for all matching instantiations.
+In the above example, the @pair( F *, T * )@ parameter to @value_p@ is such a type; its expansion is below and it is used as the type of the variables @q@ and @r@ as well, with casts for member access where appropriate:
+\begin{lstlisting}
+struct _pair_conc0 {
+	void * first;
+	void * second;
+};
+\end{lstlisting}
+
+
+\subsection{Dynamic Generic-Types}
+
+Though \CFA implements concrete generic-types efficiently, it also has a fully general system for dynamic generic types.
+As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller.
+Dynamic generic-types also have an \emph{offset array} containing structure-member offsets.
+A dynamic generic-union needs no such offset array, as all members are at offset 0, but size and alignment are still necessary.
+Access to members of a dynamic structure is provided at runtime via base-displacement addressing with the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime.
+
+The offset arrays are statically generated where possible.
+If a dynamic generic-type is declared to be passed or returned by value from a polymorphic function, the translator can safely assume the generic type is complete (\ie has a known layout) at any call-site, and the offset array is passed from the caller;
+if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro.
+As an example, @p.second@ in the @value@ function above is implemented as @*(p + _offsetof_pair[1])@, where @p@ is a @void *@, and @_offsetof_pair@ is the offset array passed into @value@ for @pair( const char *, T )@.
+The offset array @_offsetof_pair@ is generated at the call site as @size_t _offsetof_pair[] = { offsetof(_pair_conc1, first), offsetof(_pair_conc1, second) }@.
+
+In some cases the offset arrays cannot be statically generated.
+For instance, modularity is generally provided in C by including an opaque forward-declaration of a structure and associated accessor and mutator functions in a header file, with the actual implementations in a separately-compiled @.c@ file.
+\CFA supports this pattern for generic types, but the caller does not know the actual layout or size of the dynamic generic-type, and only holds it by a pointer.
+The \CFA translator automatically generates \emph{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller.
+These layout functions take as arguments pointers to size and alignment variables and a caller-allocated array of member offsets, as well as the size and alignment of all @sized@ parameters to the generic structure (un@sized@ parameters are forbidden from being used in a context that affects layout).
+Results of these layout functions are cached so that they are only computed once per type per function. %, as in the example below for @pair@.
+Layout functions also allow generic types to be used in a function definition without reflecting them in the function signature.
+For instance, a function that strips duplicate values from an unsorted @vector(T)@ would likely have a pointer to the vector as its only explicit parameter, but use some sort of @set(T)@ internally to test for duplicate values.
+This function could acquire the layout for @set(T)@ by calling its layout function with the layout of @T@ implicitly passed into the function.
+
+Whether a type is concrete, dtype-static, or dynamic is decided solely on the @forall@'s type parameters.
+This design allows opaque forward declarations of generic types, \eg @forall(otype T)@ @struct Box@ -- like in C, all uses of @Box(T)@ can be separately compiled, and callers from other translation units know the proper calling conventions to use.
+If the definition of a structure type is included in deciding whether a generic type is dynamic or concrete, some further types may be recognized as dtype-static (\eg @forall(otype T)@ @struct unique_ptr { T * p }@ does not depend on @T@ for its layout, but the existence of an @otype@ parameter means that it \emph{could}.), but preserving separate compilation (and the associated C compatibility) in the existing design is judged to be an appropriate trade-off.
+
+
+\subsection{Applications}
+\label{sec:generic-apps}
+
+The reuse of dtype-static structure instantiations enables useful programming patterns at zero runtime cost.
+The most important such pattern is using @forall(dtype T) T *@ as a type-checked replacement for @void *@, \eg creating a lexicographic comparison for pairs of pointers used by @bsearch@ or @qsort@:
+\begin{lstlisting}
+forall(dtype T) int lexcmp( pair( T *, T * ) * a, pair( T *, T * ) * b, int (* cmp)( T *, T * ) ) {
+	return cmp( a->first, b->first ) ? : cmp( a->second, b->second );
+}
+\end{lstlisting}
+Since @pair(T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the fields of both pairs and the arguments to the comparison function match in type.
+
+Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \emph{tag-structures}.
+Sometimes information is only used for type-checking and can be omitted at runtime, \eg:
+\begin{lstlisting}
+forall(dtype Unit) struct scalar { unsigned long value; };
+struct metres {};
+struct litres {};
+
+forall(dtype U) scalar(U) ?+?( scalar(U) a, scalar(U) b ) {
+	return (scalar(U)){ a.value + b.value };
+}
+scalar(metres) half_marathon = { 21093 };
+scalar(litres) swimming_pool = { 2500000 };
+scalar(metres) marathon = half_marathon + half_marathon;
+scalar(litres) two_pools = swimming_pool + swimming_pool;
+marathon + swimming_pool;					$\C{// compilation ERROR}$
+\end{lstlisting}
+@scalar@ is a dtype-static type, so all uses have a single structure definition, containing @unsigned long@, and can share the same implementations of common functions like @?+?@.
+These implementations may even be separately compiled, unlike \CC template functions.
+However, the \CFA type-checker ensures matching types are used by all calls to @?+?@, preventing nonsensical computations like adding a length to a volume.
+
+
+\section{Tuples}
+\label{sec:tuples}
+
+In many languages, functions can return at most one value;
+however, many operations have multiple outcomes, some exceptional.
+Consider C's @div@ and @remquo@ functions, which return the quotient and remainder for a division of integer and floating-point values, respectively.
+\begin{lstlisting}
+typedef struct { int quo, rem; } div_t;		$\C{// from include stdlib.h}$
+div_t div( int num, int den );
+double remquo( double num, double den, int * quo );
+div_t qr = div( 13, 5 );					$\C{// return quotient/remainder aggregate}$
+int q;
+double r = remquo( 13.5, 5.2, &q );			$\C{// return remainder, alias quotient}$
+\end{lstlisting}
+@div@ aggregates the quotient/remainder in a structure, while @remquo@ aliases a parameter to an argument.
+Both approaches are awkward.
+Alternatively, a programming language can directly support returning multiple values, \eg in \CFA:
+\begin{lstlisting}
+[ int, int ] div( int num, int den );		$\C{// return two integers}$
+[ double, double ] div( double num, double den ); $\C{// return two doubles}$
+int q, r;									$\C{// overloaded variable names}$
+double q, r;
+[ q, r ] = div( 13, 5 );					$\C{// select appropriate div and q, r}$
+[ q, r ] = div( 13.5, 5.2 );				$\C{// assign into tuple}$
+\end{lstlisting}
+Clearly, this approach is straightforward to understand and use;
+therefore, why do few programming languages support this obvious feature or provide it awkwardly?
+The answer is that there are complex consequences that cascade through multiple aspects of the language, especially the type-system.
+This section show these consequences and how \CFA handles them.
+
+
+\subsection{Tuple Expressions}
+
+The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site.
+The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly.
+As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \emph{tuple}.
+
+However, functions also use \emph{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg:
+\begin{lstlisting}
+printf( "%d %d\n", div( 13, 5 ) );			$\C{// return values seperated into arguments}$
+\end{lstlisting}
+Here, the values returned by @div@ are composed with the call to @printf@ by flattening the tuple into separate arguments.
+However, the \CFA type-system must support significantly more complex composition:
+\begin{lstlisting}
+[ int, int ] foo$\(_1\)$( int );			$\C{// overloaded foo functions}$
+[ double ] foo$\(_2\)$( int );
+void bar( int, double, double );
+bar( foo( 3 ), foo( 3 ) );
+\end{lstlisting}
+The type-resolver only has the tuple return-types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list.
+No combination of @foo@s are an exact match with @bar@'s parameters, so the resolver applies C conversions.
+The minimal cost is @bar( foo@$_1$@( 3 ), foo@$_2$@( 3 ) )@, giving (@int@, {\color{ForestGreen}@int@}, @double@) to (@int@, {\color{ForestGreen}@double@}, @double@) with one {\color{ForestGreen}safe} (widening) conversion from @int@ to @double@ versus ({\color{red}@double@}, {\color{ForestGreen}@int@}, {\color{ForestGreen}@int@}) to ({\color{red}@int@}, {\color{ForestGreen}@double@}, {\color{ForestGreen}@double@}) with one {\color{red}unsafe} (narrowing) conversion from @double@ to @int@ and two safe conversions.
+
+
+\subsection{Tuple Variables}
+
+An important observation from function composition is that new variable names are not required to initialize parameters from an MRVF.
+\CFA also allows declaration of tuple variables that can be initialized from an MRVF, since it can be awkward to declare multiple variables of different types, \eg:
+\begin{lstlisting}
+[ int, int ] qr = div( 13, 5 );				$\C{// tuple-variable declaration and initialization}$
+[ double, double ] qr = div( 13.5, 5.2 );
+\end{lstlisting}
+where the tuple variable-name serves the same purpose as the parameter name(s).
+Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown in C.
+
+One way to access the tuple-variable components is with assignment or composition:
+\begin{lstlisting}
+[ q, r ] = qr;								$\C{// access tuple-variable components}$
+printf( "%d %d\n", qr );
+\end{lstlisting}
+\CFA also supports \emph{tuple indexing} to access single components of a tuple expression:
+\begin{lstlisting}
+[int, int] * p = &qr;						$\C{// tuple pointer}$
+int rem = qr`.1`;							$\C{// access remainder}$
+int quo = div( 13, 5 )`.0`;					$\C{// access quotient}$
+p`->0` = 5;									$\C{// change quotient}$
+bar( qr`.1`, qr );							$\C{// pass remainder and quotient/remainder}$
+rem = [42, div( 13, 5 )]`.0.1`;				$\C{// access 2nd component of 1st component of tuple expression}$
+\end{lstlisting}
+
+
+\subsection{Flattening and Restructuring}
+
+In function call contexts, tuples support implicit flattening and restructuring conversions.
+Tuple flattening recursively expands a tuple into the list of its basic components.
+Tuple structuring packages a list of expressions into a value of tuple type, \eg:
+%\lstDeleteShortInline@%
+%\par\smallskip
+%\begin{tabular}{@{}l@{\hspace{1.5\parindent}}||@{\hspace{1.5\parindent}}l@{}}
+\begin{lstlisting}
+int f( int, int );
+int g( [int, int] );
+int h( int, [int, int] );
+[int, int] x;
+int y;
+f( x );			$\C{// flatten}$
+g( y, 10 );		$\C{// structure}$
+h( x, y );		$\C{// flatten and structure}$
+\end{lstlisting}
+%\end{lstlisting}
+%&
+%\begin{lstlisting}
+%\end{tabular}
+%\smallskip\par\noindent
+%\lstMakeShortInline@%
+In the call to @f@, @x@ is implicitly flattened so the components of @x@ are passed as the two arguments.
+In the call to @g@, the values @y@ and @10@ are structured into a single argument of type @[int, int]@ to match the parameter type of @g@.
+Finally, in the call to @h@, @x@ is flattened to yield an argument list of length 3, of which the first component of @x@ is passed as the first parameter of @h@, and the second component of @x@ and @y@ are structured into the second argument of type @[int, int]@.
+The flexible structure of tuples permits a simple and expressive function call syntax to work seamlessly with both SRVF and MRVF, and with any number of arguments of arbitrarily complex structure.
+
+
+\subsection{Tuple Assignment}
+
+An assignment where the left side is a tuple type is called \emph{tuple assignment}.
+There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called \emph{multiple} and \emph{mass assignment}, respectively.
+%\lstDeleteShortInline@%
+%\par\smallskip
+%\begin{tabular}{@{}l@{\hspace{1.5\parindent}}||@{\hspace{1.5\parindent}}l@{}}
+\begin{lstlisting}
+int x = 10;
+double y = 3.5;
+[int, double] z;
+z = [x, y];									$\C{// multiple assignment}$
+[x, y] = z;									$\C{// multiple assignment}$
+z = 10;										$\C{// mass assignment}$
+[y, x] = 3.14;								$\C{// mass assignment}$
+\end{lstlisting}
+%\end{lstlisting}
+%&
+%\begin{lstlisting}
+%\end{tabular}
+%\smallskip\par\noindent
+%\lstMakeShortInline@%
+Both kinds of tuple assignment have parallel semantics, so that each value on the left and right side is evaluated before any assignments occur.
+As a result, it is possible to swap the values in two variables without explicitly creating any temporary variables or calling a function, \eg, @[x, y] = [y, x]@.
+This semantics means mass assignment differs from C cascading assignment (\eg @a = b = c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
+For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@;
+whereas, C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@.
+Finally, tuple assignment is an expression where the result type is the type of the left-hand side of the assignment, just like all other assignment expressions in C.
+This example shows mass, multiple, and cascading assignment used in one expression:
+\begin{lstlisting}
+void f( [int, int] );
+f( [x, y] = z = 1.5 );						$\C{// assignments in parameter list}$
+\end{lstlisting}
+
+
+\subsection{Member Access}
+
+It is also possible to access multiple fields from a single expression using a \emph{member-access}.
+The result is a single tuple-valued expression whose type is the tuple of the types of the members, \eg:
+\begin{lstlisting}
+struct S { int x; double y; char * z; } s;
+s.[x, y, z] = 0;
+\end{lstlisting}
+Here, the mass assignment sets all members of @s@ to zero.
+Since tuple-index expressions are a form of member-access expression, it is possible to use tuple-index expressions in conjunction with member tuple expressions to manually restructure a tuple (\eg rearrange, drop, and duplicate components).
+%\lstDeleteShortInline@%
+%\par\smallskip
+%\begin{tabular}{@{}l@{\hspace{1.5\parindent}}||@{\hspace{1.5\parindent}}l@{}}
+\begin{lstlisting}
+[int, int, long, double] x;
+void f( double, long );
+x.[0, 1] = x.[1, 0];						$\C{// rearrange: [x.0, x.1] = [x.1, x.0]}$
+f( x.[0, 3] );								$\C{// drop: f(x.0, x.3)}$
+[int, int, int] y = x.[2, 0, 2];			$\C{// duplicate: [y.0, y.1, y.2] = [x.2, x.0.x.2]}$
+\end{lstlisting}
+%\end{lstlisting}
+%&
+%\begin{lstlisting}
+%\end{tabular}
+%\smallskip\par\noindent
+%\lstMakeShortInline@%
+It is also possible for a member access to contain other member accesses, \eg:
+\begin{lstlisting}
+struct A { double i; int j; };
+struct B { int * k; short l; };
+struct C { int x; A y; B z; } v;
+v.[x, y.[i, j], z.k];						$\C{// [v.x, [v.y.i, v.y.j], v.z.k]}$
+\end{lstlisting}
+
+
+\begin{comment}
+\subsection{Casting}
+
+In C, the cast operator is used to explicitly convert between types.
+In \CFA, the cast operator has a secondary use as type ascription.
+That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function:
+\begin{lstlisting}
+int f();     // (1)
+double f();  // (2)
+
+f();       // ambiguous - (1),(2) both equally viable
+(int)f();  // choose (2)
+\end{lstlisting}
+
+Since casting is a fundamental operation in \CFA, casts should be given a meaningful interpretation in the context of tuples.
+Taking a look at standard C provides some guidance with respect to the way casts should work with tuples:
+\begin{lstlisting}
+int f();
+void g();
+
+(void)f();  // (1)
+(int)g();  // (2)
+\end{lstlisting}
+In C, (1) is a valid cast, which calls @f@ and discards its result.
+On the other hand, (2) is invalid, because @g@ does not produce a result, so requesting an @int@ to materialize from nothing is nonsensical.
+Generalizing these principles, any cast wherein the number of components increases as a result of the cast is invalid, while casts that have the same or fewer number of components may be valid.
+
+Formally, a cast to tuple type is valid when $T_n \leq S_m$, where $T_n$ is the number of components in the target type and $S_m$ is the number of components in the source type, and for each $i$ in $[0, n)$, $S_i$ can be cast to $T_i$.
+Excess elements ($S_j$ for all $j$ in $[n, m)$) are evaluated, but their values are discarded so that they are not included in the result expression.
+This approach follows naturally from the way that a cast to @void@ works in C.
+
+For example, in
+\begin{lstlisting}
+[int, int, int] f();
+[int, [int, int], int] g();
+
+([int, double])f();           $\C{// (1)}$
+([int, int, int])g();         $\C{// (2)}$
+([void, [int, int]])g();      $\C{// (3)}$
+([int, int, int, int])g();    $\C{// (4)}$
+([int, [int, int, int]])g();  $\C{// (5)}$
+\end{lstlisting}
+
+(1) discards the last element of the return value and converts the second element to @double@.
+Since @int@ is effectively a 1-element tuple, (2) discards the second component of the second element of the return value of @g@.
+If @g@ is free of side effects, this expression is equivalent to @[(int)(g().0), (int)(g().1.0), (int)(g().2)]@.
+Since @void@ is effectively a 0-element tuple, (3) discards the first and third return values, which is effectively equivalent to @[(int)(g().1.0), (int)(g().1.1)]@).
+
+Note that a cast is not a function call in \CFA, so flattening and structuring conversions do not occur for cast expressions\footnote{User-defined conversions have been considered, but for compatibility with C and the existing use of casts as type ascription, any future design for such conversions would require more precise matching of types than allowed for function arguments and parameters.}.
+As such, (4) is invalid because the cast target type contains 4 components, while the source type contains only 3.
+Similarly, (5) is invalid because the cast @([int, int, int])(g().1)@ is invalid.
+That is, it is invalid to cast @[int, int]@ to @[int, int, int]@.
+\end{comment}
+
+
+\subsection{Polymorphism}
+
+Tuples also integrate with \CFA polymorphism as a kind of generic type.
+Due to the implicit flattening and structuring conversions involved in argument passing, @otype@ and @dtype@ parameters are restricted to matching only with non-tuple types, \eg:
+\begin{lstlisting}
+forall(otype T, dtype U) void f( T x, U * y );
+f( [5, "hello"] );
+\end{lstlisting}
+where @[5, "hello"]@ is flattened, giving argument list @5, "hello"@, and @T@ binds to @int@ and @U@ binds to @const char@.
+Tuples, however, may contain polymorphic components.
+For example, a plus operator can be written to add two triples together.
+\begin{lstlisting}
+forall(otype T | { T ?+?( T, T ); }) [T, T, T] ?+?( [T, T, T] x, [T, T, T] y ) {
+	return [x.0 + y.0, x.1 + y.1, x.2 + y.2];
+}
+[int, int, int] x;
+int i1, i2, i3;
+[i1, i2, i3] = x + ([10, 20, 30]);
+\end{lstlisting}
+
+Flattening and restructuring conversions are also applied to tuple types in polymorphic type assertions.
+\begin{lstlisting}
+int f( [int, double], double );
+forall(otype T, otype U | { T f( T, U, U ); }) void g( T, U );
+g( 5, 10.21 );
+\end{lstlisting}
+Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution.
+This relaxation is possible by extending the thunk scheme described by~\citet{Bilson03}.
+Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function:
+\begin{lstlisting}
+int _thunk( int _p0, double _p1, double _p2 ) { return f( [_p0, _p1], _p2 ); }
+\end{lstlisting}
+so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism.
+These thunks take advantage of GCC C nested-functions to produce closures that have the usual function-pointer signature.
+
+
+\subsection{Variadic Tuples}
+\label{sec:variadic-tuples}
+
+To define variadic functions, \CFA adds a new kind of type parameter, @ttype@ (tuple type).
+Matching against a @ttype@ parameter consumes all remaining argument components and packages them into a tuple, binding to the resulting tuple of types.
+In a given parameter list, there must be at most one @ttype@ parameter that occurs last, which matches normal variadic semantics, with a strong feeling of similarity to \CCeleven variadic templates.
+As such, @ttype@ variables are also called \emph{argument packs}.
+
+Like variadic templates, the main way to manipulate @ttype@ polymorphic functions is via recursion.
+Since nothing is known about a parameter pack by default, assertion parameters are key to doing anything meaningful.
+Unlike variadic templates, @ttype@ polymorphic functions can be separately compiled.
+For example, a generalized @sum@ function written using @ttype@:
+\begin{lstlisting}
+int sum$\(_0\)$() { return 0; }
+forall(ttype Params | { int sum( Params ); } ) int sum$\(_1\)$( int x, Params rest ) {
+	return x + sum( rest );
+}
+sum( 10, 20, 30 );
+\end{lstlisting}
+Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@.
+In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list and @Params@ is bound to @[20, 30]@.
+The process continues unitl @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
+Effectively, this algorithm traces as @sum(10, 20, 30)@ $\rightarrow$ @10 + sum(20, 30)@ $\rightarrow$ @10 + (20 + sum(30))@ $\rightarrow$ @10 + (20 + (30 + sum()))@ $\rightarrow$ @10 + (20 + (30 + 0))@.
+
+It is reasonable to take the @sum@ function a step further to enforce a minimum number of arguments:
+\begin{lstlisting}
+int sum( int x, int y ) { return x + y; }
+forall(ttype Params | { int sum( int, Params ); } ) int sum( int x, int y, Params rest ) {
+	return sum( x + y, rest );
+}
+\end{lstlisting}
+One more step permits the summation of any summable type with all arguments of the same type:
+\begin{lstlisting}
+trait summable(otype T) {
+	T ?+?( T, T );
+};
+forall(otype R | summable( R ) ) R sum( R x, R y ) {
+	return x + y;
+}
+forall(otype R, ttype Params | summable(R) | { R sum(R, Params); } ) R sum(R x, R y, Params rest) {
+	return sum( x + y, rest );
+}
+\end{lstlisting}
+Unlike C variadic functions, it is unnecessary to hard code the number and expected types.
+Furthermore, this code is extendable for any user-defined type with a @?+?@ operator.
+Summing arbitrary heterogeneous lists is possible with similar code by adding the appropriate type variables and addition operators.
+
+It is also possible to write a type-safe variadic print function to replace @printf@:
+\begin{lstlisting}
+struct S { int x, y; };
+forall(otype T, ttype Params | { void print(T); void print(Params); }) void print(T arg, Params rest) {
+	print(arg);  print(rest);
+}
+void print( char * x ) { printf( "%s", x ); }
+void print( int x ) { printf( "%d", x ); }
+void print( S s ) { print( "{ ", s.x, ",", s.y, " }" ); }
+print( "s = ", (S){ 1, 2 }, "\n" );
+\end{lstlisting}
+This example showcases a variadic-template-like decomposition of the provided argument list.
+The individual @print@ functions allow printing a single element of a type.
+The polymorphic @print@ allows printing any list of types, where as each individual type has a @print@ function.
+The individual print functions can be used to build up more complicated @print@ functions, such as @S@, which cannot be done with @printf@ in C.
+
+Finally, it is possible to use @ttype@ polymorphism to provide arbitrary argument forwarding functions.
+For example, it is possible to write @new@ as a library function:
+\begin{lstlisting}
+forall( otype R, otype S ) void ?{}( pair(R, S) *, R, S );
+forall( dtype T, ttype Params | sized(T) | { void ?{}( T *, Params ); } ) T * new( Params p ) {
+	return ((T *)malloc()){ p };			$\C{// construct into result of malloc}$
+}
+pair( int, char ) * x = new( 42, '!' );
+\end{lstlisting}
+The @new@ function provides the combination of type-safe @malloc@ with a \CFA constructor call, making it impossible to forget constructing dynamically allocated objects.
+This function provides the type-safety of @new@ in \CC, without the need to specify the allocated type again, thanks to return-type inference.
+
+
+\subsection{Implementation}
+
+Tuples are implemented in the \CFA translator via a transformation into \emph{generic types}.
+For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg:
+\begin{lstlisting}
+[int, int] f() {
+	[double, double] x;
+	[int, double, int] y;
+}
+\end{lstlisting}
+is transformed into:
+\begin{lstlisting}
+forall(dtype T0, dtype T1 | sized(T0) | sized(T1)) struct _tuple2 {
+	T0 field_0;								$\C{// generated before the first 2-tuple}$
+	T1 field_1;
+};
+_tuple2(int, int) f() {
+	_tuple2(double, double) x;
+	forall(dtype T0, dtype T1, dtype T2 | sized(T0) | sized(T1) | sized(T2)) struct _tuple3 {
+		T0 field_0;							$\C{// generated before the first 3-tuple}$
+		T1 field_1;
+		T2 field_2;
+	};
+	_tuple3(int, double, int) y;
+}
+\end{lstlisting}
+\begin{sloppypar}
+Tuple expressions are then simply converted directly into compound literals, \eg @[5, 'x', 1.24]@ becomes @(_tuple3(int, char, double)){ 5, 'x', 1.24 }@.
+\end{sloppypar}
+
+\begin{comment}
+Since tuples are essentially structures, tuple indexing expressions are just field accesses:
+\begin{lstlisting}
+void f(int, [double, char]);
+[int, double] x;
+
+x.0+x.1;
+printf("%d %g\n", x);
+f(x, 'z');
+\end{lstlisting}
+Is transformed into:
+\begin{lstlisting}
+void f(int, _tuple2(double, char));
+_tuple2(int, double) x;
+
+x.field_0+x.field_1;
+printf("%d %g\n", x.field_0, x.field_1);
+f(x.field_0, (_tuple2){ x.field_1, 'z' });
+\end{lstlisting}
+Note that due to flattening, @x@ used in the argument position is converted into the list of its fields.
+In the call to @f@, the second and third argument components are structured into a tuple argument.
+Similarly, tuple member expressions are recursively expanded into a list of member access expressions.
+
+Expressions that may contain side effects are made into \emph{unique expressions} before being expanded by the flattening conversion.
+Each unique expression is assigned an identifier and is guaranteed to be executed exactly once:
+\begin{lstlisting}
+void g(int, double);
+[int, double] h();
+g(h());
+\end{lstlisting}
+Internally, this expression is converted to two variables and an expression:
+\begin{lstlisting}
+void g(int, double);
+[int, double] h();
+
+_Bool _unq0_finished_ = 0;
+[int, double] _unq0;
+g(
+	(_unq0_finished_ ? _unq0 : (_unq0 = f(), _unq0_finished_ = 1, _unq0)).0,
+	(_unq0_finished_ ? _unq0 : (_unq0 = f(), _unq0_finished_ = 1, _unq0)).1,
+);
+\end{lstlisting}
+Since argument evaluation order is not specified by the C programming language, this scheme is built to work regardless of evaluation order.
+The first time a unique expression is executed, the actual expression is evaluated and the accompanying boolean is set to true.
+Every subsequent evaluation of the unique expression then results in an access to the stored result of the actual expression.
+Tuple member expressions also take advantage of unique expressions in the case of possible impurity.
+
+Currently, the \CFA translator has a very broad, imprecise definition of impurity, where any function call is assumed to be impure.
+This notion could be made more precise for certain intrinsic, auto-generated, and builtin functions, and could analyze function bodies when they are available to recursively detect impurity, to eliminate some unique expressions.
+
+The various kinds of tuple assignment, constructors, and destructors generate GNU C statement expressions.
+A variable is generated to store the value produced by a statement expression, since its fields may need to be constructed with a non-trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.
+The use of statement expressions allows the translator to arbitrarily generate additional temporary variables as needed, but binds the implementation to a non-standard extension of the C language.
+However, there are other places where the \CFA translator makes use of GNU C extensions, such as its use of nested functions, so this restriction is not new.
+\end{comment}
+
+
+\section{Evaluation}
+\label{sec:eval}
+
+Though \CFA provides significant added functionality over C, these features have a low runtime penalty.
+In fact, \CFA's features for generic programming can enable faster runtime execution than idiomatic @void *@-based C code.
+This claim is demonstrated through a set of generic-code-based micro-benchmarks in C, \CFA, and \CC (see stack implementations in Appendix~\ref{sec:BenchmarkStackImplementation}).
+Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks would show little runtime variance, other than in length and clarity of source code.
+A more illustrative benchmark measures the costs of idiomatic usage of each language's features.
+Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ routine similar to that in Section~\ref{sec:variadic-tuples}.
+The benchmark test is similar for C and \CC.
+The experiment uses element types @int@ and @pair(_Bool, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, finds the maximum value in the other stack, and prints $N/2$ (to reduce graph height) constants.
+
+\begin{figure}
+\begin{lstlisting}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt]
+int main( int argc, char * argv[] ) {
+	FILE * out = fopen( "cfa-out.txt", "w" );
+	int maxi = 0, vali = 42;
+	stack(int) si, ti;
+
+	REPEAT_TIMED( "push_int", N, push( &si, vali ); )
+	TIMED( "copy_int", ti = si; )
+	TIMED( "clear_int", clear( &si ); )
+	REPEAT_TIMED( "pop_int", N, 
+		int xi = pop( &ti ); if ( xi > maxi ) { maxi = xi; } )
+	REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
+
+	pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
+	stack(pair(_Bool, char)) sp, tp;
+
+	REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
+	TIMED( "copy_pair", tp = sp; )
+	TIMED( "clear_pair", clear( &sp ); )
+	REPEAT_TIMED( "pop_pair", N, 
+		pair(_Bool, char) xp = pop( &tp ); if ( xp > maxp ) { maxp = xp; } )
+	REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
+	fclose(out);
+}
+\end{lstlisting}
+\caption{\protect\CFA Benchmark Test}
+\label{fig:BenchmarkTest}
+\end{figure}
+
+The structure of each benchmark implemented is: C with @void *@-based polymorphism, \CFA with the presented features, \CC with templates, and \CC using only class inheritance for polymorphism, called \CCV.
+The \CCV variant illustrates an alternative object-oriented idiom where all objects inherit from a base @object@ class, mimicking a Java-like interface;
+hence runtime checks are necessary to safely down-cast objects.
+The most notable difference among the implementations is in memory layout of generic types: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, while C and \CCV lack such a capability and instead must store generic objects via pointers to separately-allocated objects.
+For the print benchmark, idiomatic printing is used: the C and \CFA variants used @stdio.h@, while the \CC and \CCV variants used @iostream@; preliminary tests show this distinction has negligible runtime impact.
+Note, the C benchmark uses unchecked casts as there is no runtime mechanism to perform such checks, while \CFA and \CC provide type-safety statically.
+
+Figure~\ref{fig:eval} and Table~\ref{tab:eval} show the results of running the benchmark in Figure~\ref{fig:BenchmarkTest} and its C, \CC, and \CCV equivalents. 
+The graph plots the median of 5 consecutive runs of each program, with an initial warm-up run omitted.
+All code is compiled at \texttt{-O2} by GCC or G++ 6.2.0, with all \CC code compiled as \CCfourteen.
+The benchmarks are run on an Ubuntu 16.04 workstation with 16 GB of RAM and a 6-core AMD FX-6300 CPU with 3.5 GHz maximum clock frequency.
+
+\begin{figure}
+\centering
+\input{timing}
+\caption{Benchmark Timing Results (smaller is better)}
+\label{fig:eval}
+\end{figure}
+
+\begin{table}
+\caption{Properties of benchmark code}
+\label{tab:eval}
+\newcommand{\CT}[1]{\multicolumn{1}{c}{#1}}
+\begin{tabular}{rrrrr}
+									& \CT{C}	& \CT{\CFA}	& \CT{\CC}	& \CT{\CCV}		\\ \hline
+maximum memory usage (MB)			& 10001		& 2502		& 2503		& 11253			\\
+source code size (lines)			& 247		& 222		& 165		& 339			\\
+redundant type annotations (lines)	& 39		& 2			& 2			& 15			\\
+binary size (KB)					& 14		& 229		& 18		& 38			\\
+\end{tabular}
+\end{table}
+
+The C and \CCV variants are generally the slowest with the largest memory footprint, because of their less-efficient memory layout and the pointer-indirection necessary to implement generic types;
+this inefficiency is exacerbated by the second level of generic types in the pair-based benchmarks.
+By contrast, the \CFA and \CC variants run in roughly equivalent time for both the integer and pair of @_Bool@ and @char@ because the storage layout is equivalent, with the inlined libraries (\ie no separate compilation) and greater maturity of the \CC compiler contributing to its lead.
+\CCV is slower than C largely due to the cost of runtime type-checking of down-casts (implemented with @dynamic_cast@);
+There are two outliers in the graph for \CFA: all prints and pop of @pair@.
+Both of these cases result from the complexity of the C-generated polymorphic code, so that the GCC compiler is unable to optimize some dead code and condense nested calls.
+A compiler designed for \CFA could easily perform these optimizations.
+Finally, the binary size for \CFA is larger because of static linking with the \CFA libraries.
+
+\CFA is also competitive in terms of source code size, measured as a proxy for programmer effort. The line counts in Table~\ref{tab:eval} include implementations of @pair@ and @stack@ types for all four languages for purposes of direct comparison, though it should be noted that \CFA and \CC have pre-written data structures in their standard libraries that programmers would generally use instead. Use of these standard library types has minimal impact on the performance benchmarks, but shrinks the \CFA and \CC benchmarks to 73 and 54 lines, respectively. 
+On the other hand, C does not have a generic collections-library in its standard distribution, resulting in frequent reimplementation of such collection types by C programmers.
+\CCV does not use the \CC standard template library by construction, and in fact includes the definition of @object@ and wrapper classes for @bool@, @char@, @int@, and @const char *@ in its line count, which inflates this count somewhat, as an actual object-oriented language would include these in the standard library; 
+with their omission, the \CCV line count is similar to C.
+We justify the given line count by noting that many object-oriented languages do not allow implementing new interfaces on library types without subclassing or wrapper types, which may be similarly verbose.
+
+Raw line-count, however, is a fairly rough measure of code complexity;
+another important factor is how much type information the programmer must manually specify, especially where that information is not checked by the compiler.
+Such unchecked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointers arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts (\eg @object@ to @integer@ when popping a stack, or @object@ to @printable@ when printing the elements of a @pair@).
+To quantify this, the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is re-specified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression.
+The \CC benchmark uses two redundant type annotations to create a new stack nodes, while the C and \CCV benchmarks have several such annotations spread throughout their code.
+The two instances in which the \CFA benchmark still uses redundant type specifiers are to cast the result of a polymorphic @malloc@ call (the @sizeof@ argument is inferred by the compiler).
+These uses are similar to the @new@ expressions in \CC, though the \CFA compiler's type resolver should shortly render even these type casts superfluous.
+
+
+\section{Related Work}
+
+
+\subsection{Polymorphism}
+
+\CC is the most similar language to \CFA;
+both are extensions to C with source and runtime backwards compatibility.
+The fundamental difference is in their engineering approach to C compatibility and programmer expectation.
+While \CC provides good backwards compatibility with C, it has a steep learning curve for many of its extensions.
+For example, polymorphism is provided via three disjoint mechanisms: overloading, inheritance, and templates.
+The overloading is restricted because resolution does not use the return type, inheritance requires learning object-oriented programming and coping with a restricted nominal-inheritance hierarchy, templates cannot be separately compiled resulting in compilation/code bloat and poor error messages, and determining how these mechanisms interact and which to use is confusing.
+In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate-compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.
+The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed properties for a type.
+Until \CC~\citet{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
+furthermore, \CC concepts are restricted to template polymorphism.
+
+Cyclone~\citep{Grossman06} also provides capabilities for polymorphic functions and existential types, similar to \CFA's @forall@ functions and generic types.
+Cyclone existential types can include function pointers in a construct similar to a virtual function-table, but these pointers must be explicitly initialized at some point in the code, a tedious and potentially error-prone process.
+Furthermore, Cyclone's polymorphic functions and types are restricted to abstraction over types with the same layout and calling convention as @void *@, \ie only pointer types and @int@.
+In \CFA terms, all Cyclone polymorphism must be dtype-static.
+While the Cyclone design provides the efficiency benefits discussed in Section~\ref{sec:generic-apps} for dtype-static polymorphism, it is more restrictive than \CFA's general model.
+\citet{Smith98} present Polymorphic C, an ML dialect with polymorphic functions and C-like syntax and pointer types; it lacks many of C's features, however, most notably structure types, and so is not a practical C replacement.
+
+\citet{obj-c-book} is an industrially successful extension to C.
+However, Objective-C is a radical departure from C, using an object-oriented model with message-passing.
+Objective-C did not support type-checked generics until recently \citet{xcode7}, historically using less-efficient runtime checking of object types.
+The~\citet{GObject} framework also adds object-oriented programming with runtime type-checking and reference-counting garbage-collection to C;
+these features are more intrusive additions than those provided by \CFA, in addition to the runtime overhead of reference-counting.
+\citet{Vala} compiles to GObject-based C, adding the burden of learning a separate language syntax to the aforementioned demerits of GObject as a modernization path for existing C code-bases.
+Java~\citep{Java8} included generic types in Java~5, which are type-checked at compilation and type-erased at runtime, similar to \CFA's.
+However, in Java, each object carries its own table of method pointers, while \CFA passes the method pointers separately to maintain a C-compatible layout.
+Java is also a garbage-collected, object-oriented language, with the associated resource usage and C-interoperability burdens.
+
+D~\citep{D}, Go, and~\citet{Rust} are modern, compiled languages with abstraction features similar to \CFA traits, \emph{interfaces} in D and Go and \emph{traits} in Rust.
+However, each language represents a significant departure from C in terms of language model, and none has the same level of compatibility with C as \CFA.
+D and Go are garbage-collected languages, imposing the associated runtime overhead.
+The necessity of accounting for data transfer between managed runtimes and the unmanaged C runtime complicates foreign-function interfaces to C.
+Furthermore, while generic types and functions are available in Go, they are limited to a small fixed set provided by the compiler, with no language facility to define more.
+D restricts garbage collection to its own heap by default, while Rust is not garbage-collected, and thus has a lighter-weight runtime more interoperable with C.
+Rust also possesses much more powerful abstraction capabilities for writing generic code than Go.
+On the other hand, Rust's borrow-checker provides strong safety guarantees but is complex and difficult to learn and imposes a distinctly idiomatic programming style.
+\CFA, with its more modest safety features, allows direct ports of C code while maintaining the idiomatic style of the original source.
+
+
+\subsection{Tuples/Variadics}
+
+Many programming languages have some form of tuple construct and/or variadic functions, \eg SETL, C, KW-C, \CC, D, Go, Java, ML, and Scala.
+SETL~\cite{SETL} is a high-level mathematical programming language, with tuples being one of the primary data types.
+Tuples in SETL allow subscripting, dynamic expansion, and multiple assignment.
+C provides variadic functions through @va_list@ objects, but the programmer is responsible for managing the number of arguments and their types, so the mechanism is type unsafe.
+KW-C~\cite{Buhr94a}, a predecessor of \CFA, introduced tuples to C as an extension of the C syntax, taking much of its inspiration from SETL.
+The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-field access.
+\CCeleven introduced @std::tuple@ as a library variadic template structure.
+Tuples are a generalization of @std::pair@, in that they allow for arbitrary length, fixed-size aggregation of heterogeneous values.
+Operations include @std::get<N>@ to extract vales, @std::tie@ to create a tuple of references used for assignment, and lexicographic comparisons.
+\CCseventeen proposes \emph{structured bindings}~\cite{Sutter15} to eliminate pre-declaring variables and use of @std::tie@ for binding the results.
+This extension requires the use of @auto@ to infer the types of the new variables, so complicated expressions with a non-obvious type must be documented with some other mechanism.
+Furthermore, structured bindings are not a full replacement for @std::tie@, as it always declares new variables.
+Like \CC, D provides tuples through a library variadic-template structure.
+Go does not have tuples but supports MRVF.
+Java's variadic functions appear similar to C's but are type-safe using homogeneous arrays, which are less useful than \CFA's heterogeneously-typed variadic functions.
+Tuples are a fundamental abstraction in most functional programming languages, such as Standard ML~\cite{sml} and~\cite{Scala}, which decompose tuples using pattern matching.
+
+
+\section{Conclusion and Future Work}
+
+The goal of \CFA is to provide an evolutionary pathway for large C development-environments to be more productive and safer, while respecting the talent and skill of C programmers.
+While other programming languages purport to be a better C, they are in fact new and interesting languages in their own right, but not C extensions.
+The purpose of this paper is to introduce \CFA, and showcase two language features that illustrate the \CFA type-system and approaches taken to achieve the goal of evolutionary C extension.
+The contributions are a powerful type-system using parametric polymorphism and overloading, generic types, and tuples, which all have complex interactions.
+The work is a challenging design, engineering, and implementation exercise.
+On the surface, the project may appear as a rehash of similar mechanisms in \CC.
+However, every \CFA feature is different than its \CC counterpart, often with extended functionality, better integration with C and its programmers, and always supporting separate compilation.
+All of these new features are being used by the \CFA development-team to build the \CFA runtime-system.
+Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable.
+
+There is ongoing work on a wide range of \CFA feature extensions, including reference types, arrays with size, exceptions, concurrent primitives and modules.
+(While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these additional extensions.)
+In addition, there are interesting future directions for the polymorphism design.
+Notably, \CC template functions trade compile time and code bloat for optimal runtime of individual instantiations of polymorphic functions.
+\CFA polymorphic functions use dynamic virtual-dispatch; 
+the runtime overhead of this approach is low, but not as low as inlining, and it may be beneficial to provide a mechanism for performance-sensitive code.
+Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization).
+These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat.
+In general, we believe separate compilation, producing smaller code, works well with loaded hardware-caches, which may offset the benefit of larger inlined-code.
+
+
+\begin{acks}
+The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, and Thierry Delisle on the features described in this paper, and thank Magnus Madsen and the three anonymous reviewers for valuable feedback.
+This work is supported in part by a corporate partnership with \grantsponsor{Huawei}{Huawei Ltd.}{http://www.huawei.com}, and Aaron Moss and Peter Buhr are funded by the \grantsponsor{Natural Sciences and Engineering Research Council} of Canada.
+% the first author's \grantsponsor{NSERC-PGS}{NSERC PGS D}{http://www.nserc-crsng.gc.ca/Students-Etudiants/PG-CS/BellandPostgrad-BelletSuperieures_eng.asp} scholarship.
+\end{acks}
+
+
+\bibliographystyle{ACM-Reference-Format}
+\bibliography{cfa}
+
+
+\appendix
+
+\section{Benchmark Stack Implementation}
+\label{sec:BenchmarkStackImplementation}
+
+\lstset{basicstyle=\linespread{0.9}\sf\small}
+
+Throughout, @/***/@ designates a counted redundant type annotation.
+
+\smallskip\noindent
+\CFA
+\begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
+forall(otype T) struct stack_node {
+	T value;
+	stack_node(T) * next;
+};
+forall(otype T) void ?{}(stack(T) * s) { (&s->head){ 0 }; }
+forall(otype T) void ?{}(stack(T) * s, stack(T) t) {
+	stack_node(T) ** crnt = &s->head;
+	for ( stack_node(T) * next = t.head; next; next = next->next ) {
+		*crnt = ((stack_node(T) *)malloc()){ next->value }; /***/
+		stack_node(T) * acrnt = *crnt;
+		crnt = &acrnt->next;
+	}
+	*crnt = 0;
+}
+forall(otype T) stack(T) ?=?(stack(T) * s, stack(T) t) {
+	if ( s->head == t.head ) return *s;
+	clear(s);
+	s{ t };
+	return *s;
+}
+forall(otype T) void ^?{}(stack(T) * s) { clear(s); }
+forall(otype T) _Bool empty(const stack(T) * s) { return s->head == 0; }
+forall(otype T) void push(stack(T) * s, T value) {
+	s->head = ((stack_node(T) *)malloc()){ value, s->head }; /***/
+}
+forall(otype T) T pop(stack(T) * s) {
+	stack_node(T) * n = s->head;
+	s->head = n->next;
+	T x = n->value;
+	^n{};
+	free(n);
+	return x;
+}
+forall(otype T) void clear(stack(T) * s) {
+	for ( stack_node(T) * next = s->head; next; ) {
+		stack_node(T) * crnt = next;
+		next = crnt->next;
+		delete(crnt);
+	}
+	s->head = 0;
+}
+\end{lstlisting}
+
+\medskip\noindent
+\CC
+\begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
+template<typename T> class stack {
+	struct node {
+		T value;
+		node * next;
+		node( const T & v, node * n = nullptr ) : value(v), next(n) {}
+	};
+	node * head;
+	void copy(const stack<T>& o) {
+		node ** crnt = &head;
+		for ( node * next = o.head;; next; next = next->next ) {
+			*crnt = new node{ next->value }; /***/
+			crnt = &(*crnt)->next;
+		}
+		*crnt = nullptr;
+	}
+  public:
+	stack() : head(nullptr) {}
+	stack(const stack<T>& o) { copy(o); }
+	stack(stack<T> && o) : head(o.head) { o.head = nullptr; }
+	~stack() { clear(); }
+	stack & operator= (const stack<T>& o) {
+		if ( this == &o ) return *this;
+		clear();
+		copy(o);
+		return *this;
+	}
+	stack & operator= (stack<T> && o) {
+		if ( this == &o ) return *this;
+		head = o.head;
+		o.head = nullptr;
+		return *this;
+	}
+	bool empty() const { return head == nullptr; }
+	void push(const T & value) { head = new node{ value, head };  /***/ }
+	T pop() {
+		node * n = head;
+		head = n->next;
+		T x = std::move(n->value);
+		delete n;
+		return x;
+	}
+	void clear() {
+		for ( node * next = head; next; ) {
+			node * crnt = next;
+			next = crnt->next;
+			delete crnt;
+		}
+		head = nullptr;
+	}
+};
+\end{lstlisting}
+
+\medskip\noindent
+C
+\begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
+struct stack_node {
+	void * value;
+	struct stack_node * next;
+};
+struct stack new_stack() { return (struct stack){ NULL }; /***/ }
+void copy_stack(struct stack * s, const struct stack * t, void * (*copy)(const void *)) {
+	struct stack_node ** crnt = &s->head;
+	for ( struct stack_node * next = t->head; next; next = next->next ) {
+		*crnt = malloc(sizeof(struct stack_node)); /***/
+		**crnt = (struct stack_node){ copy(next->value) }; /***/
+		crnt = &(*crnt)->next;
+	}
+	*crnt = 0;
+}
+_Bool stack_empty(const struct stack * s) { return s->head == NULL; }
+void push_stack(struct stack * s, void * value) {
+	struct stack_node * n = malloc(sizeof(struct stack_node)); /***/
+	*n = (struct stack_node){ value, s->head }; /***/
+	s->head = n;
+}
+void * pop_stack(struct stack * s) {
+	struct stack_node * n = s->head;
+	s->head = n->next;
+	void * x = n->value;
+	free(n);
+	return x;
+}
+void clear_stack(struct stack * s, void (*free_el)(void *)) {
+	for ( struct stack_node * next = s->head; next; ) {
+		struct stack_node * crnt = next;
+		next = crnt->next;
+		free_el(crnt->value);
+		free(crnt);
+	}
+	s->head = NULL;
+}
+\end{lstlisting}
+
+\medskip\noindent
+\CCV
+\begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
+stack::node::node( const object & v, node * n ) : value( v.new_copy() ), next( n ) {}
+void stack::copy(const stack & o) {
+	node ** crnt = &head;
+	for ( node * next = o.head; next; next = next->next ) {
+		*crnt = new node{ *next->value };
+		crnt = &(*crnt)->next;
+	}
+	*crnt = nullptr;
+}
+stack::stack() : head(nullptr) {}
+stack::stack(const stack & o) { copy(o); }
+stack::stack(stack && o) : head(o.head) { o.head = nullptr; }
+stack::~stack() { clear(); }
+stack & stack::operator= (const stack & o) {
+	if ( this == &o ) return *this;
+	clear();
+	copy(o);
+	return *this;
+}
+stack & stack::operator= (stack && o) {
+	if ( this == &o ) return *this;
+	head = o.head;
+	o.head = nullptr;
+	return *this;
+}
+bool stack::empty() const { return head == nullptr; }
+void stack::push(const object & value) { head = new node{ value, head }; /***/ }
+ptr<object> stack::pop() {
+	node * n = head;
+	head = n->next;
+	ptr<object> x = std::move(n->value);
+	delete n;
+	return x;
+}
+void stack::clear() {
+	for ( node * next = head; next; ) {
+		node * crnt = next;
+		next = crnt->next;
+		delete crnt;
+	}
+	head = nullptr;
+}
+\end{lstlisting}
+
+
+\begin{comment}
+
+\subsubsection{bench.h}
+(\texttt{bench.hpp} is similar.)
+
+\lstinputlisting{evaluation/bench.h}
+
+\subsection{C}
+
+\subsubsection{c-stack.h} ~
+
+\lstinputlisting{evaluation/c-stack.h}
+
+\subsubsection{c-stack.c} ~
+
+\lstinputlisting{evaluation/c-stack.c}
+
+\subsubsection{c-pair.h} ~
+
+\lstinputlisting{evaluation/c-pair.h}
+
+\subsubsection{c-pair.c} ~
+
+\lstinputlisting{evaluation/c-pair.c}
+
+\subsubsection{c-print.h} ~
+
+\lstinputlisting{evaluation/c-print.h}
+
+\subsubsection{c-print.c} ~
+
+\lstinputlisting{evaluation/c-print.c}
+
+\subsubsection{c-bench.c} ~
+
+\lstinputlisting{evaluation/c-bench.c}
+
+\subsection{\CFA}
+
+\subsubsection{cfa-stack.h} ~
+
+\lstinputlisting{evaluation/cfa-stack.h}
+
+\subsubsection{cfa-stack.c} ~
+
+\lstinputlisting{evaluation/cfa-stack.c}
+
+\subsubsection{cfa-print.h} ~
+
+\lstinputlisting{evaluation/cfa-print.h}
+
+\subsubsection{cfa-print.c} ~
+
+\lstinputlisting{evaluation/cfa-print.c}
+
+\subsubsection{cfa-bench.c} ~
+
+\lstinputlisting{evaluation/cfa-bench.c}
+
+\subsection{\CC}
+
+\subsubsection{cpp-stack.hpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-stack.hpp}
+
+\subsubsection{cpp-print.hpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-print.hpp}
+
+\subsubsection{cpp-bench.cpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-bench.cpp}
+
+\subsection{\CCV}
+
+\subsubsection{object.hpp} ~
+
+\lstinputlisting[language=c++]{evaluation/object.hpp}
+
+\subsubsection{cpp-vstack.hpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-vstack.hpp}
+
+\subsubsection{cpp-vstack.cpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-vstack.cpp}
+
+\subsubsection{cpp-vprint.hpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-vprint.hpp}
+
+\subsubsection{cpp-vbench.cpp} ~
+
+\lstinputlisting[language=c++]{evaluation/cpp-vbench.cpp}
+\end{comment}
+
+\end{document}
+
+% Local Variables: %
+% tab-width: 4 %
+% compile-command: "make" %
+% End: %
Index: doc/papers/OOPSLA17/mail
===================================================================
--- doc/papers/OOPSLA17/mail	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/mail	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,350 @@
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Registered #20 "Generic and Tuple Types with
+ Efficient..."
+To: Aaron Moss <a3moss@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
+Date: Wed,  5 Apr 2017 19:20:09 +0000 (UTC)
+
+Submission #20 has been registered at the 2017 ACM SIGPLAN International
+Conference on Object-Oriented Programming, Systems, Languages, and
+Applications (OOPSLA'17) site.
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+     Authors: Aaron Moss (University of Waterloo)
+              Robert Schluntz (University of Waterloo)
+              Peter Buhr (University of Waterloo)
+  Paper site: https://oopsla17.hotcrp.com/paper/20?cap=020aob3NvMVprLQ
+
+The submission has not yet been uploaded. Further updates are allowed until
+18 Apr 2017 7:59:59am EDT. If the submission is not ready for review by 18
+Apr 2017 7:59:59am EDT, it will not be considered.
+
+Contact Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu> with any questions
+or concerns.
+
+- OOPSLA'17 Submissions
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Account information
+To: Peter Buhr <pabuhr@uwaterloo.ca>
+Date: Wed,  5 Apr 2017 19:20:09 +0000 (UTC)
+
+Greetings,
+
+An account has been created for you at the 2017 ACM SIGPLAN International
+Conference on Object-Oriented Programming, Systems, Languages, and
+Applications (OOPSLA'17) submissions site.
+
+        Site: https://oopsla17.hotcrp.com/
+       Email: pabuhr@uwaterloo.ca
+    Password: htrkiy5slu8drk
+
+Use the link below to sign in.
+
+https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca&password=htrkiy5slu8drk
+
+If you already have an account under a different email address, you may
+merge this new account into that one. Go to your profile page and select
+"Merge with another account".
+
+Contact Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu> with any questions
+or concerns.
+
+- OOPSLA'17 Submissions
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Updated #20 "Generic and Tuple Types with Efficient..."
+To: Aaron Moss <a3moss@uwaterloo.ca>, Peter Buhr <pabuhr@uwaterloo.ca>
+Date: Tue, 18 Apr 2017 03:05:16 +0000 (UTC)
+
+Submission #20 has been updated at the 2017 ACM SIGPLAN International
+Conference on Object-Oriented Programming, Systems, Languages, and
+Applications (OOPSLA'17) site.
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+     Authors: Aaron Moss (University of Waterloo)
+              Robert Schluntz (University of Waterloo)
+              Peter Buhr (University of Waterloo)
+  Paper site: https://oopsla17.hotcrp.com/paper/20?cap=020aob3NvMVprLQ
+
+You will receive email when reviews are available. Further updates are
+allowed until 18 Apr 2017 7:59:59am EDT.
+
+Contact Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu> with any questions
+or concerns.
+
+- OOPSLA'17 Submissions
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
+To: Peter Buhr <pabuhr@uwaterloo.ca>
+Cc: jonathan.aldrich@cs.cmu.edu
+Reply-To: jonathan.aldrich@cs.cmu.edu
+Date: Wed,  7 Jun 2017 13:33:40 +0000 (UTC)
+
+Dear Peter Buhr,
+
+The author response period for OOPSLA has started, and will continue until
+the end of June 10th (Anywhere on Earth).  No email with a snapshot of your
+reviews will be sent: you can see the live version of reviews (including
+current updates) on the HotCRP system (links at the bottom).
+
+An author response should aim to:
+ -correct reviewers' mistakes or misunderstandings
+ -offer new information only when this addresses reviewers' concerns (e.g.,
+"I wonder if A might work better...";  "we tried that, but...")
+ -answer explicit questions by the reviewers. The key questions will be in a
+designated "Questions for Author Response" entry of a review.
+
+Please keep in mind that an author response is *not* a "rebuttal". You are
+not rebutting an opponent's arguments with your own, in front of an
+audience that weighs both sets of arguments. Instead, your audience is the
+same reviewers who offered the comments in the first place, and their
+subjective weighing of different factors is very unlikely to change.
+
+During author response, please keep in mind that the reviewers are still
+unaware of author identity. If you need to refer to author-identifying
+information during your response, the ideal course of action is to place it
+at an external location and include a URL, with an explicit warning (e.g.,
+"WARNING: following this link will reveal author identity").
+
+As with all external resources, your response should be self-contained,
+without consulting them. That is, the author-visible external URL is just
+evidence, but the claim that this evidence supports should be clear in the
+response text. For instance:
+"we have received public feedback from the developers of X that confirm the
+issue [supporting URL] (WARNING: following this link will reveal author
+identity)"
+
+Your paper's access information is below:
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+  Paper site: https://oopsla17.hotcrp.com/paper/20
+
+Use the link below to sign in to the site.
+
+https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
+
+Please contact me <jonathan.aldrich@cs.cmu.edu> with any questions or
+concerns.
+
+Best Regards and wishes for a constructive response,
+
+Jonathan Aldrich
+
+
+
+From: "OOPSLA'17 HotCRP" <noreply@oopsla17.hotcrp.com>
+Subject: [OOPSLA'17] Paper #20 "Generic and Tuple Types with Efficient..."
+To: Peter Buhr <pabuhr@uwaterloo.ca>
+Cc: jonathan.aldrich@cs.cmu.edu
+Reply-To: jonathan.aldrich@cs.cmu.edu
+Date: Tue, 20 Jun 2017 00:33:10 +0000 (UTC)
+
+Dear Peter Buhr,
+
+I regret to inform you that your submission to OOPSLA'17 listed below has not
+been selected for the second phase of the review process. I understand this is
+not welcome news but selection was very competitive: 157 of the 223 papers
+submitted did not advance to the second phase. For several of these, there was
+a clear impression that in the future they can evolve into some of the
+strongest results of our community.
+
+       Title: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+  Paper site: https://oopsla17.hotcrp.com/paper/20
+  Login link: https://oopsla17.hotcrp.com/?email=pabuhr%40uwaterloo.ca
+
+Below you will find reviews, as well as author-visible comments--the latter may
+include further communication. I hope you will find the reviewers' feedback
+useful.
+
+Best Regards,
+
+- Jonathan Aldrich <jonathan.aldrich@cs.cmu.edu>, for OOPSLA 2017
+Submissions
+
+
+
+===========================================================================
+                           OOPSLA'17 Review #20A
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: C. Weak paper, though I will not fight
+                                        strongly against it
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+This presents an extension of the C programming language that tries to preserve the character of the existing language, while adding tuples and generics. Unlike C++ templates, generics preserve separate compilation. Types are represented at runtime, if needed, by size and alignment values, along with pointers to the code for any needed operators. A microbenchmark performance comparison is provided.
+
+                      ===== Comments for author =====
+
+This is an interesting extension to C, that may be of interest to some C programmers. It generally seems to be fairly well engineered, and mostly respects C's design goals.
+
+Unfortunately, there have been enough proposals for extended C dialects that this sort of design is tough to sell. And I don't think the evaluation really went far enough to make that case.
+
+The ideas in the paper don't appear to be fundamentally new. The idea of passing types as runtime objects has certainly been explored before. An additional ancient reference is http://dl.acm.org/citation.cfm?doid=13310.13330.
+
+There seems to be a new idea of minimally describing types using alignment and size attributes instead of (?) pointers to assignment operators and the like. But this scheme is not very well described. Notably, it is not clear how, say, a struct with atomic field or bit-fields would be described.
+
+I wasn't quite clear on the extent to which operator overloading is supported. The MAX example appears to me like it would be quite controversial among C programmers. 
+
+It is not obvious that type inference here always converges. An outline of the algorithm would be useful.
+
+Above all, this needs experience results from a more complete implementation.
+
+Details:
+
+Relying on TIOBE here seems a bit dubious. Since it counts web pages, and C isn't exactly new and hot, it may actually understate your case.
+
+The print example seems a little simplistic, since it's not clear how it handles formatting.
+
+"does not using the return type"
+
+              ===== Questions for authors’ response =====
+
+How are atomics, volatile, and bit-fields in structs handled?
+
+===========================================================================
+                           OOPSLA'17 Review #20B
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+The authors present an extension to C, adding universal polymorphism and tuples. These features are described in prose. There is an implementation, though this is not described in depth in the paper. There is a benchmark evaluation.
+
+                      ===== Comments for author =====
+
+The paper is well-written and the concepts explained well. It is nice to see work in the low-level/C space - I believe that it is an area that has not been well-served by the OOPSLA community. My concerns with the paper are that the contribution is rather small and the concepts are not well-evaluated; specifically this is a language design paper and there is no attempt to evaluate the actual language design.
+
+While it is reasonable to describe only a couple of features in a paper, I would then expect a detailed description of the implementation and/or a formalism with proven safety properties and a thorough evaluation of the design. For a paper which only describes the design of a language the bar is higher than two features - for example, a description of a 'large' language such as D or Rust, even then I would expect a stronger evaluation.
+
+## On the design of C-forall
+
+There are some interesting points in the design of generics, notably the otype/dtype distinction. The design seems reasonable and follows what I would expect from other languages. The design for tuples is more unusual - the usual design of simple anonymous records with anonymous fields is extended with a mix of 'spread'ing, variadics, and implicit conversions. Importantly, the authors neither justify nor evaluate this departure - that is a severe omission for this paper. Furthermore, the only in-depth description of the implementation in the paper concerns tuples, and it seems to me that this is only interesting because of the unusual design - further reason for justifying it.
+
+## Evaluation
+
+The paper evaluates the implementation of C-forall with (effectively) a single micro-benchmark. That benchmark seems to show that C-forall performs worse than C++ on every measure, but this is not really discussed.
+
+A better performance evaluation would consist of multiple tests, both micro-benchmarks and realistic code and would test C-forall compared to alternatives (D, Rust, Go, etc.) not just C/C++.
+
+However, performance is not the really interesting thing to test here. The authors propose a new language and while performance is an important consideration for systems languages, it is far from the most important. I would like to see the usability of the language tested with user studies of different kinds (various levels of skill-level and coding scenarios). The authors could also use case studies or programming idioms to compare programming in C-forall vs the alternatives (again, comparing with D, Rust, etc. is more interesting to me than C).
+
+Finally, in designing C-forall, the authors make several assumptions about why C programmers use C. These should be backed up either with evaluation or citation. Statements in the paper certainly do not reflect my experience discussing language design with C programmers, and I would like to see them verified.
+
+
+## Related work
+
+The related work section is broad and gives good descriptions of other languages. However, the comparisons between languages focus more on the high-level goals of the language. It would be more interesting to focus on the details of the languages - the comparisons between Cyclone, C++, Java, and C-forall generics are good, I would like to see more of this with D and Rust, which are the more modern alternatives to C-forall (for example, Rust's notion of Sized and ?Sized types seems similar to otypes/dtypes).
+
+The related work is really missing any discussion of why the C-forall design choices are better than other languages. To clarify, I mean the specific design of generics and tuples, c.f., the suitability of the language in general because of garbage collection or learning difficulties.
+
+===========================================================================
+                           OOPSLA'17 Review #20C
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: Z. I am not an expert; my evaluation
+                                        is that of an informed outsider
+
+                         ===== Paper summary =====
+
+The paper presents two language features of "Cforall": generics and tuples.
+
+                      ===== Comments for author =====
+
+The authors really need to talk about C++ as early as possible IMHO. That's the first thing that came to mind when reading the abstract: how is this different from C++?
+
+Comparison with C++:
+The main difference with C++ seems to be that Cforall favors separate compilation at the expense of runtime overhead while C++ systematically avoids any runtime overhead (at the expense of slow compilation times). C++ approach makes more sense IMHO. While it's true that people where using C for almost everything 30 years ago, that is just not true anymore. Most people writing C today are doing system programming, otherwise there would be using a higher level programming language (C#, Java etc ...).
+Now, when doing system programming, one needs very fine grain control over the resources: memory layout, etc ...
+It is pretty clear to me that the people writing that kind of code will favor generics that do not cost any overhead at runtime, otherwise they would be writing Java in the first place.
+The authors need to better justify the runtime overhead, or give escape hatches for those who don't want to pay that cost at runtime.
+They very often go back to the benefit of separate compilation, but that's not enough IMHO. Here is a proposal: why not have 2 modes, one called debug mode, used while developing the code, that would compile generics with a runtime overhead. Another, called production, that would unfold the world like C++ does?
+
+About Tuples:
+The section about tuples is too long. I would have spent more time explaining generics.
+
+Feedback:
+"This installation base"
+Unclear what you mean by that.
+
+"Prior projects ... but failed ..."
+Hummm ... What about C++.
+
+"... object-oriented or functional programming with garbage collection ..."
+You are really mixing apples and oranges here. Many C programmers have nothing agains object-oriented features, not even functional programming (C++ 11 adds
+a bunch of features proving my point), but it's clear that most of them feel very strongly against automated garbage collection.
+
+"In many cases, C++ is often ..."
+This sentence feels like it is coming out of nowhere.
+
+"... the polymorphic runtime-cost ..."
+Is there any way to avoid that overhead? It's true it will make the compiler faster, but there are cases where the user might not want to pay for
+the overhead at runtime. Is there a way to force the compiler to specialize the code?
+
+"... to write a type-safe Cforall wrapper malloc based ..."
+That cannot be true in general. Malloc produces a pointer (of any type), given an integer (the size).
+It looks like Cforall is assuming that the integer is the result of a call to sizeof (a good practice in C).
+However, if that's the case, it should be explained.
+
+"... allows variable overloading ..."
+How are conflict resolved? In other words, what happens when two variables could be used?
+
+"... reuses the generated structure declarations where appropriate."
+This is too vague.
+
+"... have multiple outcomes, some exceptional."
+Humm, I would say these two things are distinct. Let's just way that this way of presenting things is strange, I woulds ay that a function can either
+return one or multiple values or throw an exception. Not that some of the values returned are "exceptional".
+
+"The type-resolver ..."
+What's that? Type-checker? Type-inference?
+
+"... applies C conversions."
+Noooo! That's exactly what leads to very subtle bugs. Is there any way to stop those conversions from happening?
+
+"The minimal cost ..."
+In what regard? Runtime cost? How does the "resolver" know how expensive the conversions are?
+
+"z = 10 // mass assignments"
+That stuff is completely unreadable. Why not introduce a new operator?
+
+"... roughly equivalent time ..."
+Well, C++ looks faster to me.
+
+"... is restricted because the resolution does not using ..."
+Did you mean, does not use?
+
+"... D and go are garbage collected ..."
+Yes, but in D, the use of the GC is optional.
+
+"... while respecting the talent and skill of C programmers."
+Are you implying that other approaches are not?
+
+"On the surface, the project may appear as a rehash of similar mechanisms in C++."
+Absolutely.
+
+"... integration with C and its programmers ..."
+Bold claim. What makes you think you are integrated with programmers? Number of users?
+
+"... inline annotation at polymorphic function call sites to create a template-specialization ..."
+This should have been mentioned sooner. Plus conflating inlining and specialization is unfortunate.
+Does "inline" also inline the function? Or does it only specialize the code?
+If it also inline, that's a very unfortunate design. I might want to specialize the code, but without inlining ...
+How do I specialize a recursive function?
Index: doc/papers/OOPSLA17/refereeReport.txt
===================================================================
--- doc/papers/OOPSLA17/refereeReport.txt	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
+++ doc/papers/OOPSLA17/refereeReport.txt	(revision 5f20b30579817affc723dc7ade61baa416bdf43e)
@@ -0,0 +1,178 @@
+===========================================================================
+                           OOPSLA'17 Review #20A
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: C. Weak paper, though I will not fight
+                                        strongly against it
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+This presents an extension of the C programming language that tries to preserve the character of the existing language, while adding tuples and generics. Unlike C++ templates, generics preserve separate compilation. Types are represented at runtime, if needed, by size and alignment values, along with pointers to the code for any needed operators. A microbenchmark performance comparison is provided.
+
+                      ===== Comments for author =====
+
+This is an interesting extension to C, that may be of interest to some C programmers. It generally seems to be fairly well engineered, and mostly respects C's design goals.
+
+Unfortunately, there have been enough proposals for extended C dialects that this sort of design is tough to sell. And I don't think the evaluation really went far enough to make that case.
+
+The ideas in the paper don't appear to be fundamentally new. The idea of passing types as runtime objects has certainly been explored before. An additional ancient reference is http://dl.acm.org/citation.cfm?doid=13310.13330.
+
+There seems to be a new idea of minimally describing types using alignment and size attributes instead of (?) pointers to assignment operators and the like. But this scheme is not very well described. Notably, it is not clear how, say, a struct with atomic field or bit-fields would be described.
+
+I wasn't quite clear on the extent to which operator overloading is supported. The MAX example appears to me like it would be quite controversial among C programmers. 
+
+It is not obvious that type inference here always converges. An outline of the algorithm would be useful.
+
+Above all, this needs experience results from a more complete implementation.
+
+Details:
+
+Relying on TIOBE here seems a bit dubious. Since it counts web pages, and C isn't exactly new and hot, it may actually understate your case.
+
+The print example seems a little simplistic, since it's not clear how it handles formatting.
+
+"does not using the return type"
+
+              ===== Questions for authors’ response =====
+
+How are atomics, volatile, and bit-fields in structs handled?
+
+===========================================================================
+                           OOPSLA'17 Review #20B
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: X. I am an expert in this area
+
+                         ===== Paper summary =====
+
+The authors present an extension to C, adding universal polymorphism and tuples. These features are described in prose. There is an implementation, though this is not described in depth in the paper. There is a benchmark evaluation.
+
+                      ===== Comments for author =====
+
+The paper is well-written and the concepts explained well. It is nice to see work in the low-level/C space - I believe that it is an area that has not been well-served by the OOPSLA community. My concerns with the paper are that the contribution is rather small and the concepts are not well-evaluated; specifically this is a language design paper and there is no attempt to evaluate the actual language design.
+
+While it is reasonable to describe only a couple of features in a paper, I would then expect a detailed description of the implementation and/or a formalism with proven safety properties and a thorough evaluation of the design. For a paper which only describes the design of a language the bar is higher than two features - for example, a description of a 'large' language such as D or Rust, even then I would expect a stronger evaluation.
+
+## On the design of C-forall
+
+There are some interesting points in the design of generics, notably the otype/dtype distinction. The design seems reasonable and follows what I would expect from other languages. The design for tuples is more unusual - the usual design of simple anonymous records with anonymous fields is extended with a mix of 'spread'ing, variadics, and implicit conversions. Importantly, the authors neither justify nor evaluate this departure - that is a severe omission for this paper. Furthermore, the only in-depth description of the implementation in the paper concerns tuples, and it seems to me that this is only interesting because of the unusual design - further reason for justifying it.
+
+## Evaluation
+
+The paper evaluates the implementation of C-forall with (effectively) a single micro-benchmark. That benchmark seems to show that C-forall performs worse than C++ on every measure, but this is not really discussed.
+
+A better performance evaluation would consist of multiple tests, both micro-benchmarks and realistic code and would test C-forall compared to alternatives (D, Rust, Go, etc.) not just C/C++.
+
+However, performance is not the really interesting thing to test here. The authors propose a new language and while performance is an important consideration for systems languages, it is far from the most important. I would like to see the usability of the language tested with user studies of different kinds (various levels of skill-level and coding scenarios). The authors could also use case studies or programming idioms to compare programming in C-forall vs the alternatives (again, comparing with D, Rust, etc. is more interesting to me than C).
+
+Finally, in designing C-forall, the authors make several assumptions about why C programmers use C. These should be backed up either with evaluation or citation. Statements in the paper certainly do not reflect my experience discussing language design with C programmers, and I would like to see them verified.
+
+
+## Related work
+
+The related work section is broad and gives good descriptions of other languages. However, the comparisons between languages focus more on the high-level goals of the language. It would be more interesting to focus on the details of the languages - the comparisons between Cyclone, C++, Java, and C-forall generics are good, I would like to see more of this with D and Rust, which are the more modern alternatives to C-forall (for example, Rust's notion of Sized and ?Sized types seems similar to otypes/dtypes).
+
+The related work is really missing any discussion of why the C-forall design choices are better than other languages. To clarify, I mean the specific design of generics and tuples, c.f., the suitability of the language in general because of garbage collection or learning difficulties.
+
+===========================================================================
+                           OOPSLA'17 Review #20C
+---------------------------------------------------------------------------
+ Paper #20: Generic and Tuple Types with Efficient Dynamic Layout in C∀
+---------------------------------------------------------------------------
+
+                      Overall merit: D. Reject
+                         Confidence: Z. I am not an expert; my evaluation
+                                        is that of an informed outsider
+
+                         ===== Paper summary =====
+
+The paper presents two language features of "Cforall": generics and tuples.
+
+                      ===== Comments for author =====
+
+The authors really need to talk about C++ as early as possible IMHO. That's the first thing that came to mind when reading the abstract: how is this different from C++?
+
+Comparison with C++:
+The main difference with C++ seems to be that Cforall favors separate compilation at the expense of runtime overhead while C++ systematically avoids any runtime overhead (at the expense of slow compilation times). C++ approach makes more sense IMHO. While it's true that people where using C for almost everything 30 years ago, that is just not true anymore. Most people writing C today are doing system programming, otherwise there would be using a higher level programming language (C#, Java etc ...).
+Now, when doing system programming, one needs very fine grain control over the resources: memory layout, etc ...
+It is pretty clear to me that the people writing that kind of code will favor generics that do not cost any overhead at runtime, otherwise they would be writing Java in the first place.
+The authors need to better justify the runtime overhead, or give escape hatches for those who don't want to pay that cost at runtime.
+They very often go back to the benefit of separate compilation, but that's not enough IMHO. Here is a proposal: why not have 2 modes, one called debug mode, used while developing the code, that would compile generics with a runtime overhead. Another, called production, that would unfold the world like C++ does?
+
+About Tuples:
+The section about tuples is too long. I would have spent more time explaining generics.
+
+Feedback:
+"This installation base"
+Unclear what you mean by that.
+
+"Prior projects ... but failed ..."
+Hummm ... What about C++.
+
+"... object-oriented or functional programming with garbage collection ..."
+You are really mixing apples and oranges here. Many C programmers have nothing agains object-oriented features, not even functional programming (C++ 11 adds
+a bunch of features proving my point), but it's clear that most of them feel very strongly against automated garbage collection.
+
+"In many cases, C++ is often ..."
+This sentence feels like it is coming out of nowhere.
+
+"... the polymorphic runtime-cost ..."
+Is there any way to avoid that overhead? It's true it will make the compiler faster, but there are cases where the user might not want to pay for
+the overhead at runtime. Is there a way to force the compiler to specialize the code?
+
+"... to write a type-safe Cforall wrapper malloc based ..."
+That cannot be true in general. Malloc produces a pointer (of any type), given an integer (the size).
+It looks like Cforall is assuming that the integer is the result of a call to sizeof (a good practice in C).
+However, if that's the case, it should be explained.
+
+"... allows variable overloading ..."
+How are conflict resolved? In other words, what happens when two variables could be used?
+
+"... reuses the generated structure declarations where appropriate."
+This is too vague.
+
+"... have multiple outcomes, some exceptional."
+Humm, I would say these two things are distinct. Let's just way that this way of presenting things is strange, I woulds ay that a function can either
+return one or multiple values or throw an exception. Not that some of the values returned are "exceptional".
+
+"The type-resolver ..."
+What's that? Type-checker? Type-inference?
+
+"... applies C conversions."
+Noooo! That's exactly what leads to very subtle bugs. Is there any way to stop those conversions from happening?
+
+"The minimal cost ..."
+In what regard? Runtime cost? How does the "resolver" know how expensive the conversions are?
+
+"z = 10 // mass assignments"
+That stuff is completely unreadable. Why not introduce a new operator?
+
+"... roughly equivalent time ..."
+Well, C++ looks faster to me.
+
+"... is restricted because the resolution does not using ..."
+Did you mean, does not use?
+
+"... D and go are garbage collected ..."
+Yes, but in D, the use of the GC is optional.
+
+"... while respecting the talent and skill of C programmers."
+Are you implying that other approaches are not?
+
+"On the surface, the project may appear as a rehash of similar mechanisms in C++."
+Absolutely.
+
+"... integration with C and its programmers ..."
+Bold claim. What makes you think you are integrated with programmers? Number of users?
+
+"... inline annotation at polymorphic function call sites to create a template-specialization ..."
+This should have been mentioned sooner. Plus conflating inlining and specialization is unfortunate.
+Does "inline" also inline the function? Or does it only specialize the code?
+If it also inline, that's a very unfortunate design. I might want to specialize the code, but without inlining ...
+How do I specialize a recursive function?
