<body class="_toc-left">
<style type="text/css">
@font-face {
  font-family: octicons-link;
  src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}

.markdown-body {
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  line-height: 1.5;
  color: #24292e;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-size: 16px;
  line-height: 1.5;
  word-wrap: break-word;
}

.markdown-body .pl-c {
  color: #6a737d;
}

.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
  color: #005cc5;
}

.markdown-body .pl-e,
.markdown-body .pl-en {
  color: #6f42c1;
}

.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
  color: #24292e;
}

.markdown-body .pl-ent {
  color: #22863a;
}

.markdown-body .pl-k {
  color: #d73a49;
}

.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
  color: #032f62;
}

.markdown-body .pl-v,
.markdown-body .pl-smw {
  color: #e36209;
}

.markdown-body .pl-bu {
  color: #b31d28;
}

.markdown-body .pl-ii {
  color: #fafbfc;
  background-color: #b31d28;
}

.markdown-body .pl-c2 {
  color: #fafbfc;
  background-color: #d73a49;
}

.markdown-body .pl-c2::before {
  content: "^M";
}

.markdown-body .pl-sr .pl-cce {
  font-weight: bold;
  color: #22863a;
}

.markdown-body .pl-ml {
  color: #735c0f;
}

.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
  font-weight: bold;
  color: #005cc5;
}

.markdown-body .pl-mi {
  font-style: italic;
  color: #24292e;
}

.markdown-body .pl-mb {
  font-weight: bold;
  color: #24292e;
}

.markdown-body .pl-md {
  color: #b31d28;
  background-color: #ffeef0;
}

.markdown-body .pl-mi1 {
  color: #22863a;
  background-color: #f0fff4;
}

.markdown-body .pl-mc {
  color: #e36209;
  background-color: #ffebda;
}

.markdown-body .pl-mi2 {
  color: #f6f8fa;
  background-color: #005cc5;
}

.markdown-body .pl-mdr {
  font-weight: bold;
  color: #6f42c1;
}

.markdown-body .pl-ba {
  color: #586069;
}

.markdown-body .pl-sg {
  color: #959da5;
}

.markdown-body .pl-corl {
  text-decoration: underline;
  color: #032f62;
}

.markdown-body .octicon {
  display: inline-block;
  vertical-align: text-top;
  fill: currentColor;
}

.markdown-body a {
  background-color: transparent;
  -webkit-text-decoration-skip: objects;
}

.markdown-body a:active,
.markdown-body a:hover {
  outline-width: 0;
}

.markdown-body strong {
  font-weight: inherit;
}

.markdown-body strong {
  font-weight: bolder;
}

.markdown-body h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

.markdown-body img {
  border-style: none;
}

.markdown-body svg:not(:root) {
  overflow: hidden;
}

.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
  font-family: monospace, monospace;
  font-size: 1em;
}

.markdown-body hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible;
}

.markdown-body input {
  font: inherit;
  margin: 0;
}

.markdown-body input {
  overflow: visible;
}

.markdown-body [type="checkbox"] {
  box-sizing: border-box;
  padding: 0;
}

.markdown-body * {
  box-sizing: border-box;
}

.markdown-body input {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

.markdown-body a {
  color: #0366d6;
  text-decoration: none;
}

.markdown-body a:hover {
  text-decoration: underline;
}

.markdown-body strong {
  font-weight: 600;
}

.markdown-body hr {
  height: 0;
  margin: 15px 0;
  overflow: hidden;
  background: transparent;
  border: 0;
  border-bottom: 1px solid #dfe2e5;
}

.markdown-body hr::before {
  display: table;
  content: "";
}

.markdown-body hr::after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body table {
  border-spacing: 0;
  border-collapse: collapse;
}

.markdown-body td,
.markdown-body th {
  padding: 0;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body h1 {
  font-size: 32px;
  font-weight: 600;
}

.markdown-body h2 {
  font-size: 24px;
  font-weight: 600;
}

.markdown-body h3 {
  font-size: 20px;
  font-weight: 600;
}

.markdown-body h4 {
  font-size: 16px;
  font-weight: 600;
}

.markdown-body h5 {
  font-size: 14px;
  font-weight: 600;
}

.markdown-body h6 {
  font-size: 12px;
  font-weight: 600;
}

.markdown-body p {
  margin-top: 0;
  margin-bottom: 10px;
}

.markdown-body blockquote {
  margin: 0;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 0;
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body ol ol,
.markdown-body ul ol {
  list-style-type: lower-roman;
}

.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
  list-style-type: lower-alpha;
}

.markdown-body dd {
  margin-left: 0;
}

.markdown-body code {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
}

.markdown-body pre {
  margin-top: 0;
  margin-bottom: 0;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 12px;
}

.markdown-body .octicon {
  vertical-align: text-bottom;
}

.markdown-body .pl-0 {
  padding-left: 0 !important;
}

.markdown-body .pl-1 {
  padding-left: 4px !important;
}

.markdown-body .pl-2 {
  padding-left: 8px !important;
}

.markdown-body .pl-3 {
  padding-left: 16px !important;
}

.markdown-body .pl-4 {
  padding-left: 24px !important;
}

.markdown-body .pl-5 {
  padding-left: 32px !important;
}

.markdown-body .pl-6 {
  padding-left: 40px !important;
}

.markdown-body::before {
  display: table;
  content: "";
}

.markdown-body::after {
  display: table;
  clear: both;
  content: "";
}

.markdown-body>*:first-child {
  margin-top: 0 !important;
}

.markdown-body>*:last-child {
  margin-bottom: 0 !important;
}

.markdown-body a:not([href]) {
  color: inherit;
  text-decoration: none;
}

.markdown-body .anchor {
  float: left;
  padding-right: 4px;
  margin-left: -20px;
  line-height: 1;
}

.markdown-body .anchor:focus {
  outline: none;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
  margin-top: 0;
  margin-bottom: 16px;
}

.markdown-body hr {
  height: 0.25em;
  padding: 0;
  margin: 24px 0;
  background-color: #e1e4e8;
  border: 0;
}

.markdown-body blockquote {
  padding: 0 1em;
  color: #6a737d;
  border-left: 0.25em solid #dfe2e5;
}

.markdown-body blockquote>:first-child {
  margin-top: 0;
}

.markdown-body blockquote>:last-child {
  margin-bottom: 0;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font-size: 11px;
  line-height: 10px;
  color: #444d56;
  vertical-align: middle;
  background-color: #fafbfc;
  border: solid 1px #c6cbd1;
  border-bottom-color: #959da5;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #959da5;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
  margin-top: 24px;
  margin-bottom: 16px;
  font-weight: 600;
  line-height: 1.25;
}

.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
  color: #1b1f23;
  vertical-align: middle;
  visibility: hidden;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
  text-decoration: none;
}

.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
  visibility: visible;
}

.markdown-body h1 {
  padding-bottom: 0.3em;
  font-size: 2em;
  border-bottom: 1px solid #eaecef;
}

.markdown-body h2 {
  padding-bottom: 0.3em;
  font-size: 1.5em;
  border-bottom: 1px solid #eaecef;
}

.markdown-body h3 {
  font-size: 1.25em;
}

.markdown-body h4 {
  font-size: 1em;
}

.markdown-body h5 {
  font-size: 0.875em;
}

.markdown-body h6 {
  font-size: 0.85em;
  color: #6a737d;
}

.markdown-body ul,
.markdown-body ol {
  padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
  margin-top: 0;
  margin-bottom: 0;
}

.markdown-body li>p {
  margin-top: 16px;
}

.markdown-body li+li {
  margin-top: 0.25em;
}

.markdown-body dl {
  padding: 0;
}

.markdown-body dl dt {
  padding: 0;
  margin-top: 16px;
  font-size: 1em;
  font-style: italic;
  font-weight: 600;
}

.markdown-body dl dd {
  padding: 0 16px;
  margin-bottom: 16px;
}

.markdown-body table {
  display: block;
  width: 100%;
  overflow: auto;
}

.markdown-body table th {
  font-weight: 600;
}

.markdown-body table th,
.markdown-body table td {
  padding: 6px 13px;
  border: 1px solid #dfe2e5;
}

.markdown-body table tr {
  background-color: #fff;
  border-top: 1px solid #c6cbd1;
}

.markdown-body table tr:nth-child(2n) {
  background-color: #f6f8fa;
}

.markdown-body img {
  max-width: 100%;
  box-sizing: content-box;
  background-color: #fff;
}

.markdown-body img[align=right] {
  padding-left: 20px;
}

.markdown-body img[align=left] {
  padding-right: 20px;
}

.markdown-body code {
  padding: 0;
  padding-top: 0.2em;
  padding-bottom: 0.2em;
  margin: 0;
  font-size: 85%;
  background-color: rgba(27,31,35,0.05);
  border-radius: 3px;
}

.markdown-body code::before,
.markdown-body code::after {
  letter-spacing: -0.2em;
  content: "\00a0";
}

.markdown-body pre {
  word-wrap: normal;
}

.markdown-body pre>code {
  padding: 0;
  margin: 0;
  font-size: 100%;
  word-break: normal;
  white-space: pre;
  background: transparent;
  border: 0;
}

.markdown-body .highlight {
  margin-bottom: 16px;
}

.markdown-body .highlight pre {
  margin-bottom: 0;
  word-break: normal;
}

.markdown-body .highlight pre,
.markdown-body pre {
  padding: 16px;
  overflow: auto;
  font-size: 85%;
  line-height: 1.45;
  background-color: #f6f8fa;
  border-radius: 3px;
}

.markdown-body pre code {
  display: inline;
  max-width: auto;
  padding: 0;
  margin: 0;
  overflow: visible;
  line-height: inherit;
  word-wrap: normal;
  background-color: transparent;
  border: 0;
}

.markdown-body pre code::before,
.markdown-body pre code::after {
  content: normal;
}

.markdown-body .full-commit .btn-outline:not(:disabled):hover {
  color: #005cc5;
  border-color: #005cc5;
}

.markdown-body kbd {
  display: inline-block;
  padding: 3px 5px;
  font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
  line-height: 10px;
  color: #444d56;
  vertical-align: middle;
  background-color: #fafbfc;
  border: solid 1px #d1d5da;
  border-bottom-color: #c6cbd1;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #c6cbd1;
}

.markdown-body :checked+.radio-label {
  position: relative;
  z-index: 1;
  border-color: #0366d6;
}

.markdown-body .task-list-item {
  list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
  margin-top: 3px;
}

.markdown-body .task-list-item input {
  margin: 0 0.2em 0.25em -1.6em;
  vertical-align: middle;
}

.markdown-body hr {
  border-bottom-color: #eee;
}

/*Markdown Viewer*/
.markdown-body summary:hover { cursor: pointer; }
.markdown-body ul li p { margin: 0; }

/* content.css */

i
/*global*/
html, body {
  padding: 0 !important; margin: 0 !important;
  width: auto !important; max-width: 100% !important;
}

pre#_markdown {
  word-wrap: break-word;
  white-space: pre-wrap;
}

/*github theme*/
.markdown-body {
  overflow: auto;

  min-width: 888px;
  max-width: 888px;

  background-color: #fff;
  border: 1px solid #ddd;

  padding: 45px;
  margin: 20px auto;
}
.markdown-body #_html>*:first-child {
  margin-top: 0 !important;
}
.markdown-body #_html>*:last-child {
  margin-bottom: 0 !important;
}
.markdown-body img {
  background-color: transparent;
}

/*all other themes*/
.markdown-theme {
  box-sizing: border-box;
  max-width: 100% !important;
  padding: 20px !important;
  margin: 0 auto !important;
}
@media (max-width: 767px) {
  .markdown-theme { width: auto !important; }
}
@media (min-width: 768px) and (max-width: 992px) {
  .markdown-theme { width: 713px !important; }
}
@media (min-width: 992px) and (max-width: 1200px) {
  .markdown-theme { width: 937px !important; }
}
@media (min-width: 1200px) {
  .markdown-theme { width: 1145px !important; }
}

/*toc*/
body {
  display: flex;
}
body._toc-left { padding-left: 300px !important; }
body._toc-right { padding-right: 300px !important; }
#_toc {
  position: fixed;
  top: 0; bottom: 0; left: 0;
  width: 300px;
  height: 100%;
  background: #fafafa;
  overflow-y: auto;
  overflow-x: hidden;
}
#_toc #_ul {
  padding: 0 0 0 20px !important;
  margin: 0 !important;
}
#_toc #_ul a {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
  font-size: 14px !important;
  line-height: 17px !important;
  color: #364149 !important;
  font-weight: normal !important;
  font-style: normal !important;
  text-decoration: none !important;
  text-transform: none !important;
  letter-spacing: 0.2px !important;
  background: none !important;
  border: 0 !important;
  padding: 10px 15px !important;
  display: block !important;
}
#_toc #_ul a:hover {
  text-decoration: underline !important;
}

/*anchor link*/
@font-face {
  font-family: octicons-link;
  src: url(data:font/woff;charset=utf-8;base64,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) format('woff');
}

.octicon {
  font: normal normal 16px 'octicons-link';
  line-height: 1;
  display: inline-block;
  text-decoration: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.octicon-link:before { content: '\f05c'; }

.octicon-link {
  display: none;
  color: #000;
  vertical-align: middle;
}

.anchor {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
  height: 1em;
  padding-left: 8px;
  margin-left: -28px;
  line-height: 1;
  text-decoration: none;
}
.markdown-body h1:hover .octicon-link,
.markdown-body h2:hover .octicon-link,
.markdown-body h3:hover .octicon-link,
.markdown-body h4:hover .octicon-link,
.markdown-body h5:hover .octicon-link,
.markdown-body h6:hover .octicon-link {
  display: inline-block;
}

/*emojione*/
.emojione {
  /* Emoji Sizing */
  font-size: inherit;
  height: 3ex;
  width: 3.1ex;
  min-height: 20px;
  min-width: 20px;

  /* Inline alignment adjust the margins  */
  display: inline-block;
  margin: -.2ex .15em .2ex;
  line-height: normal;
  vertical-align: middle;
}

img.emojione {
  /* prevent img stretch */
  width: auto;
}

/* prism */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:rgba(255,255,255,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
</style>
<div id="_html" class="markdown-body" style="
    border: 0;
    margin: 0;
">
<table>
<tbody>
<tr>
<td>Doc. No.:</td>
<td>P1221R1</td>
</tr>
<tr>
<td>Date:</td>
<td>2018-10-03</td>
</tr>
<tr>
<td>Reply To:</td>
<td>Jason Rice 
<a href="mailto:ricejasonf@gmail.com">ricejasonf@gmail.com</a></td>
</tr>
<tr>
<td>Title:</td>
<td>Parametric Expressions</td>
</tr>
<tr>
<td>Audience:</td>
<td>Evolution Working Group</td>
</tr>
</tbody>
</table>
<h1 id="parametric-expressions"><a class="anchor" name="parametric-expressions" href="#parametric-expressions"><span class="octicon octicon-link"></span></a>Parametric Expressions</h1>
<p>Try it out: <a href="https://godbolt.org/z/Zo9ozy">https://godbolt.org/z/Zo9ozy</a></p>
<h2 id="abstract"><a class="anchor" name="abstract" href="#abstract"><span class="octicon octicon-link"></span></a>Abstract</h2>
<p>The purpose of this paper is to propose a hygienic macro that transforms expressions during semantic
analysis and template instantiation. This can replace macros in certain cases and enable more idiomatic
code, operations on packs, and have potentially faster compile times versus function templates.</p>
<p>There are two types of transformations, <em>transparent</em> and <em>opaque</em>, the latter of which supports multiple
statements and cleanups via RAII. Both are hygienically scoped.</p>
<p>Consider the following declaration syntax:</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">using</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">auto</span> a<span class="token punctuation">,</span> <span class="token keyword">auto</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>Here is a function-like declaration that has the same behaviour as a function without creating
a function type, but the body still has its own scope. </p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">40</span><span class="token punctuation">;</span>
  <span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token function">add</span><span class="token punctuation">(</span>i<span class="token operator">++</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// the same as</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">40</span><span class="token punctuation">;</span>
  <span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> a <span class="token operator">=</span> i<span class="token operator">++</span><span class="token punctuation">;</span>
    <span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
    a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token comment">// result of expression</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<blockquote>
<p>By default each input expression is bound to a variable resulting in evaluation that is consistent with
normal function call expressions. User controlled evaluation is addressed in <em>Using Parameters</em>.</p>
</blockquote>
<p>Function templates as we have them now are loaded with features such as overloading, constraints,
type deduction, SFINAE, ect.. When called not only do we get an expensive template instantiation but also
potentially large symbols and extraneous code generation all for functions we wouldn't call otherwise
unless we expected the optimizer to inline them out anyways.</p>
<p>With this tool we want to give programmers the ability to allow this inlining at an earlier stage, but
since the inlining is guaranteed and in the context of where it is called we can do things not currently
possible with normal functions without creating a special type for each invocation.</p>
<h2 id="constexpr-parameters"><a class="anchor" name="constexpr-parameters" href="#constexpr-parameters"><span class="octicon octicon-link"></span></a>Constexpr Parameters</h2>
<p>Since the invocation is inlined we easily get constexpr parameters without generating a complicated
symbol for a function prototype.</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">using</span> <span class="token function">to_int_c</span><span class="token punctuation">(</span><span class="token keyword">constexpr</span> <span class="token keyword">auto</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> std<span class="token operator">::</span>integral_constant<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span> x<span class="token operator">&gt;</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">constexpr</span> <span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token number">42</span><span class="token punctuation">;</span>
  std<span class="token operator">::</span>integral_constant<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token number">42</span><span class="token operator">&gt;</span> foo <span class="token operator">=</span> <span class="token function">to_int_c</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<h2 id="using-parameters"><a class="anchor" name="using-parameters" href="#using-parameters"><span class="octicon octicon-link"></span></a>Using Parameters</h2>
<p>With <code>using</code> as a specifier, we allow the user to take control of evaluation with macro-like semantics.</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">using</span> <span class="token function">if_</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> cond<span class="token punctuation">,</span> <span class="token keyword">using</span> <span class="token keyword">auto</span> x<span class="token punctuation">,</span> <span class="token keyword">using</span> <span class="token keyword">auto</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>cond<span class="token punctuation">)</span>
    <span class="token keyword">return</span> x<span class="token punctuation">;</span>
  <span class="token keyword">else</span>
    <span class="token keyword">return</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">if_</span><span class="token punctuation">(</span>
    <span class="token boolean">true</span><span class="token punctuation">,</span>
    <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"Hello, world!"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">"not evaluated so nothing gets printed"</span><span class="token punctuation">)</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>This has some compelling use cases for creating idiomatic interfaces:</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token comment">// customized conjunction and disjunction with short-circuit evaluation</span>

Foo<span class="token operator">*</span> y <span class="token operator">=</span> x <span class="token operator">||</span> <span class="token keyword">new</span> <span class="token function">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">auto</span> y <span class="token operator">=</span> <span class="token function">do_something</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">maybe_do_something_else</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token comment">// constexpr ternary expression</span>

<span class="token keyword">auto</span> x <span class="token operator">=</span> <span class="token function">constexpr_if</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">{</span><span class="token number">42</span><span class="token punctuation">}</span><span class="token punctuation">,</span> std<span class="token operator">::</span>make_unique<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token comment">// debug logging that eliminates evaluation in production (like macros)</span>

<span class="token keyword">namespace</span> log <span class="token punctuation">{</span>
  <span class="token keyword">struct</span> null_stream <span class="token punctuation">{</span>
    <span class="token keyword">using</span> <span class="token keyword">operator</span><span class="token operator">&lt;&lt;</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> null_stream<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>

  <span class="token keyword">using</span> <span class="token function">warn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token keyword">constexpr</span> <span class="token punctuation">(</span>log_level <span class="token operator">==</span> Warning<span class="token punctuation">)</span>
      <span class="token keyword">return</span> std<span class="token operator">::</span>wcerr<span class="token punctuation">;</span>
    <span class="token keyword">else</span>
      <span class="token keyword">return</span> null_stream<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

foo <span class="token operator">&gt;</span> <span class="token number">42</span> <span class="token operator">&amp;&amp;</span> log<span class="token operator">::</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> <span class="token string">"Foo is too large: "</span> <span class="token operator">&lt;&lt;</span> foo <span class="token operator">&lt;&lt;</span> <span class="token string">'\n'</span><span class="token punctuation">;</span>
</code></pre>
<h2 id="concise-forwarding"><a class="anchor" name="concise-forwarding" href="#concise-forwarding"><span class="octicon octicon-link"></span></a>Concise Forwarding</h2>
<p>With this feature we can implement a forwarding operator that is more concise than the existing
<code>std::forward</code>.</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">using</span> <span class="token function">fwd</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">static_cast</span><span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">auto</span> old_f <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> std<span class="token operator">::</span>forward<span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> new_f <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">fwd</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre>
<h2 id="operations-on-parameter-packs"><a class="anchor" name="operations-on-parameter-packs" href="#operations-on-parameter-packs"><span class="octicon octicon-link"></span></a>Operations on Parameter Packs</h2>
<p>We can allow unexpanded parameter packs as inputs and avoid creating tuples in many cases.</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">template</span> <span class="token operator">&lt;</span><span class="token keyword">typename</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>Xs<span class="token operator">&gt;</span>
<span class="token keyword">auto</span> <span class="token function">foo</span><span class="token punctuation">(</span>Xs<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> xs<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">auto</span> fifth_element <span class="token operator">=</span> pack<span class="token operator">::</span>get<span class="token operator">&lt;</span><span class="token number">5</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>xs<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">auto</span> bar <span class="token operator">=</span> pack<span class="token operator">::</span><span class="token function">apply</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> pack<span class="token operator">::</span><span class="token function">drop_front</span><span class="token punctuation">(</span>xs<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>The ability to return a pack can reduce the need for additional helper functions for things like
unpacking index sequences or tuples:</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token punctuation">{</span>
  <span class="token keyword">int</span> sum <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">int_seq</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">{</span>
  std<span class="token operator">::</span>array<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token operator">&gt;</span> xs <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">int</span> sum <span class="token operator">=</span> <span class="token punctuation">(</span>xs<span class="token punctuation">[</span><span class="token function">int_seq</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">{</span>
  <span class="token keyword">int</span> xs<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">int</span> sum <span class="token operator">=</span> <span class="token punctuation">(</span>xs<span class="token punctuation">[</span><span class="token function">int_seq</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">{</span>
  <span class="token keyword">constexpr</span> std<span class="token operator">::</span>tuple xs<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">constexpr</span> <span class="token keyword">int</span> sum <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token function">unpack</span><span class="token punctuation">(</span>xs<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>Don't believe it? Try it here: <a href="https://godbolt.org/z/Zo9ozy">https://godbolt.org/z/Zo9ozy</a></p>
<h2 id="friendlier-interfaces"><a class="anchor" name="friendlier-interfaces" href="#friendlier-interfaces"><span class="octicon octicon-link"></span></a>Friendlier Interfaces</h2>
<p>Some people don't like the angle bracket soup that templates can bring when interfaces require constexpr
friendly inputs. Here we can hide it with a simple wrapper (taken from <a href="https://twitter.com/Cor3ntin/status/1085826982670143488">here</a>):</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"ctre.hpp"</span></span>

<span class="token keyword">using</span> <span class="token function">match</span><span class="token punctuation">(</span><span class="token keyword">constexpr</span> <span class="token keyword">auto</span> x<span class="token punctuation">,</span> <span class="token keyword">using</span> <span class="token keyword">auto</span> sv<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">static</span> <span class="token keyword">constexpr</span> <span class="token keyword">auto</span> pattern <span class="token operator">=</span> ctll<span class="token operator">::</span>basic_fixed_string<span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">constexpr</span> <span class="token keyword">auto</span> re <span class="token operator">=</span> ctre<span class="token operator">::</span>re<span class="token operator">&lt;</span>pattern<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> re<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>sv<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>


<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">match</span><span class="token punctuation">(</span><span class="token string">"Hello.*"</span><span class="token punctuation">,</span> <span class="token string">"Hello World"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<h2 id="as-a-member-of-a-class"><a class="anchor" name="as-a-member-of-a-class" href="#as-a-member-of-a-class"><span class="octicon octicon-link"></span></a>As a Member of a Class</h2>
<p>Parametric expressions can be used as a member in conjunction with operator overloading to create an
invocable object:</p>
<pre class=" language-cpp"><code class=" language-cpp">  <span class="token keyword">struct</span> id_fn <span class="token punctuation">{</span>
    <span class="token keyword">using</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> self<span class="token punctuation">,</span> <span class="token keyword">auto</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> x<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>

  id_fn<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">static_assert</span><span class="token punctuation">(</span>std<span class="token operator">::</span>is_invocable<span class="token operator">&lt;</span>id_fn<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token operator">::</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<h2 id="transparent-transformations"><a class="anchor" name="transparent-transformations" href="#transparent-transformations"><span class="octicon octicon-link"></span></a>Transparent Transformations</h2>
<p>Specific conditions allow us to generate an expression that does not require RAII and therefore allows
the compiler to substitute the call expression directly which can also be used in SFINAE and other
contexts where variable declarations and statements are not welcome.</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">using</span> <span class="token function">funcify</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&amp;&amp;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>x<span class="token punctuation">)</span>
    <span class="token keyword">noexcept</span><span class="token punctuation">(</span><span class="token keyword">noexcept</span><span class="token punctuation">(</span><span class="token keyword">decltype</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span>std<span class="token operator">::</span>forward<span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token keyword">decltype</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span>std<span class="token operator">::</span>forward<span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">f</span><span class="token punctuation">(</span>std<span class="token operator">::</span>forward<span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">struct</span> make_array_impl <span class="token punctuation">{</span>
  <span class="token keyword">using</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> std<span class="token operator">::</span>array<span class="token operator">&lt;</span>std<span class="token operator">::</span>common_type<span class="token operator">&lt;</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">&gt;</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>x<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">constexpr</span> <span class="token keyword">auto</span> make_array <span class="token operator">=</span> <span class="token function">funcify</span><span class="token punctuation">(</span>make_array_impl<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>When a RAII scope is needed these will be referred to as opaque transformations.</p>
<h2 id="comparison-with-other-proposed-features"><a class="anchor" name="comparison-with-other-proposed-features" href="#comparison-with-other-proposed-features"><span class="octicon octicon-link"></span></a>Comparison with Other Proposed Features</h2>
<p>One of the primary benefits of this proposed feature is the compile-time performance and
the fact that it has zero impact on the type system. That with operations on packs, there are no other
proposals addressing this. However this proposed feature does have overlap with other proposed features
concerning constexpr parameters and conditional evaluation.</p>
<p>The paper <em><code>constexpr</code> Function Parameters</em> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1045r0.html">(P1045R1)</a> by David Stone proposes the <code>constexpr</code>
specifier be allowed in normal function parameter declarations effectively making the parameter
<code>constexpr</code>. The advantage that it has over this Parametric Expressions proposal is that it allows
function overloading. While this is still highly desirable, it comes with a few costs which will affect
compiler throughput. First, it requires overload resolution to check if an argument expression can be
used in a constant expression. Second, each constexpr parameter would affect the type creating a new
function type with symbols that would have to be similar to anonymous classes for each permutation of
input arguments. If this is deemed feasible, there is no conflict and the <code>constexpr</code> parameters proposed
by this paper are consistent with David Stone's proposal and the feature proposed in this paper would be
a useful augment for when overloading is not needed.</p>
<p>The paper <em>Towards A (Lazy) Forwarding Mechanism for C++</em> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0927r0.pdf">(P0927R0)</a> by James Dennet and Geoff Romer
specifically sets out to add a feature to enable conditional evaluation of function parameters. The paper
suggests the use of syntax similar to a lambda expression for the parameter declaration to specify
laziness of evaluation which is a major shift in convention as far as variable declarations are
concerned. This paper is in agreement with the motiviations stated, but the solutions are in contrast.
Having the same issues with creating a function prototype, the paper addresses the implications on the
type system suggesting that lazy parameters be added to the type system which is high impact, complex, and
in the opinion of this paper, unnecessary. This paper, however, is proposing the use of an existing
keyword in the declaration specifier which is more in keeping with existing conventions with parameter
declarations, and there is no impact on the type system which makes it a better solution.</p>
<h2 id="notable-concerns"><a class="anchor" name="notable-concerns" href="#notable-concerns"><span class="octicon octicon-link"></span></a>Notable Concerns</h2>
<h3 id="why-not-go-for-broke-and-jump-straight-into-granular-ast-node-manipulation"><a class="anchor" name="why-not-go-for-broke-and-jump-straight-into-granular-ast-node-manipulation" href="#why-not-go-for-broke-and-jump-straight-into-granular-ast-node-manipulation"><span class="octicon octicon-link"></span></a>Why not go for broke and jump straight into granular AST node manipulation?</h3>
<p>Some have suggested that we add something more akin to raw AST generation as is found in Rust macros.
While this would be a powerful superset of the feature this paper is proposing, it comes with some
issues.  One, this would make the interface <strong>significantly more complicated</strong> and inaccessible to
typical users. It also comes with the same problems with evaluation that preprocessor macros have in that
it easily allows mistakes that result in duplicate evaluation or double move operations.</p>
<p>The interface proposed with <em>Parametric Expressions</em> is such that it defaults to consistent evaluation of
input expressions by binding them to an actual variable declaration in the parameter list. If the author
of a function wants to take control of evaluation they can do so via the <code>using</code> parameter declaration
specifier and thus opt in explictly and without a lot of crazy AST syntax.</p>
<p>That said, the advent of Reflection and Metaclasses may open the door to allowing more refined control
over the AST, and this paper's stance is that this feature is <strong>forwards compatible</strong> with the possibilty
of adding <code>reflexpr</code> parameters or some similar construct to enable this superset.</p>
<h3 id="invocable-and-the-dangers-of-using-parameters"><a class="anchor" name="invocable-and-the-dangers-of-using-parameters" href="#invocable-and-the-dangers-of-using-parameters"><span class="octicon octicon-link"></span></a>Invocable and the Dangers of <code>using</code> Parameters</h3>
<p>As previously stated, <code>using</code> parameters add macro-like semantics. While the pitfalls of macros are well
understood, here is an edge case that is worth mentioning:</p>
<pre class=" language-cpp"><code class=" language-cpp"><span class="token keyword">struct</span> eval_twice_fn <span class="token punctuation">{</span>
  <span class="token keyword">using</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">using</span> <span class="token keyword">auto</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> std<span class="token operator">::</span><span class="token function">pair</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">inline</span> <span class="token keyword">constexpr</span> eval_twice<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">auto</span> result1 <span class="token operator">=</span> <span class="token function">eval_twice</span><span class="token punctuation">(</span>my<span class="token operator">::</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token string">"foo"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> result2 <span class="token operator">=</span> std<span class="token operator">::</span><span class="token function">invoke</span><span class="token punctuation">(</span>eval_twice<span class="token punctuation">,</span> my<span class="token operator">::</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token string">"foo"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p>Here the semantics are changed when used with <code>std::invoke</code>. Since <code>std::invoke</code> is a normal function, it
evaluates it and binds it to a parameter that is perfectly forwarded. The forwarding expression would
then be passed to <code>eval_twice</code> and the result of the input would get moved twice. With the call
expression the result is a pair of two distinct strings containing a pointer to their own "foo".</p>
<p><code>std::Invokable</code> does not require that the call to <code>std::invoke</code> be equality preserving on its arguments
so this is likely permissible. Regardless, this paper's stance is to allow these types of edge cases, and
leave it to the discretion of the user as the user is opting in explicitly via the <code>using</code> specifier.
Attempts to prevent these would involve complex rules and could inadvertantly rule out desirable use
cases.</p>
<h2 id="impact-on-the-existing-standard"><a class="anchor" name="impact-on-the-existing-standard" href="#impact-on-the-existing-standard"><span class="octicon octicon-link"></span></a>Impact on the Existing Standard</h2>
<p>While there is zero impact on existing features in C++, the following additions are required:</p>
<ol>
<li>
<p>Parsing the <code>using</code> keyword followed by an identifier or operator name followed by a left
parentheses would indicate the declaration of a parametric expression disambiguating from
other valid uses of the <code>using</code> keyword for other types of declarations.</p>
</li>
<li>
<p>Allow the <code>constexpr</code> specifier in parameter declarations in the context of a parametric
expression parameter list declaration.</p>
</li>
<li>
<p>The <code>using</code> keyword is used as a declaration specifier for parameter declarations in the
context a parametric expression parameter list declaration.</p>
</li>
<li>
<p>The <code>auto</code> keyword is used as placeholder for a constraint for parametric expression parameters and it
implictly promotes parameters as <code>auto&amp;&amp;</code>. This is more concise but a slight deviation from
what C++ programmers might expect.</p>
</li>
</ol>
<h2 id="implementation-experience"><a class="anchor" name="implementation-experience" href="#implementation-experience"><span class="octicon octicon-link"></span></a>Implementation Experience</h2>
<p>The proposed language feature has been implemented in a fork of Clang here: <a href="https://github.com/ricejasonf/clang/tree/parmexpr">reference implementation</a></p>
<p>From this the following are rules to specify its workings in simple terms:</p>
<ol>
<li>
<p>Declaration or invocation does not create a type.</p>
</li>
<li>
<p>The input parameter list may contain only one parameter pack in any position.</p>
</li>
<li>
<p>Input parameters do not specify a type or have type specifiers.</p>
<ul>
<li>The <strong><code>auto</code> is a placeholder for a constraint</strong> which is meant for forwards compatibility with
language Concepts.</li>
</ul>
</li>
<li>
<p>Parameter declarations can have <code>constexpr</code> or <code>using</code> specifiers which change semantics:</p>
<ul>
<li>With none of these specifiers the parameters is an forwarding reference initialized with the input
expression (like auto&amp;&amp;).</li>
<li>The <code>constexpr</code> specifier enables value initialization with an expression that must be a
constant-expression (like constexpr auto)</li>
<li>The <code>using</code> specifier does not bind the input expression to a variable, but the input expression is
substituted everywhere the name is used. (like a macro)</li>
</ul>
</li>
<li>
<p>Parameters that bind to a variable are specified to evaluate in the order of their declaration from
left to right and before evaluation of the compound statement.</p>
</li>
<li>
<p>There are two types of transformations: <em>Opaque</em> and <em>Transparent</em></p>
<ul>
<li>Transparent transformations occur when there are no variable declarations (except <code>using</code> vars),
and there is only a single statement that is a return statement. The resulting expression
substitutes the call expression that invoked it.</li>
<li>All others are opaque transformations and create a RAII scope where their return statements must be
full expressions. Typical RVO/NRVO rules for return values apply as they do in functions.</li>
</ul>
</li>
<li>
<p>Transparent transformations may have "parts" of expressions as inputs and outputs.</p>
<ul>
<li>This includes expressions that do not refer to values such as template names and others.</li>
<li>An unexpanded parameter pack is allowed as an output but is expanded before input.</li>
</ul>
</li>
<li>
<p>An Opaque transformation's return statements should follow the same rules for function return type
deduction via <code>decltype(auto)</code>.</p>
</li>
<li>
<p>Recursion is not feasible, but it is possible to achieve with templates or dependent input
expressions.</p>
</li>
<li>
<p>Operator overloading is supported along with ADL, and it creates an ambiguous call if there are other
viable candidates present.</p>
</li>
<li>
<p>When defined as a member of a class, invocations include the base expression as the first parameter.
(ie a self parameter)</p>
<ul>
<li>The reason for this is that the type is deduced and it is not compatible with the way <code>this</code>
works in function definitions. Also it gives the user flexibility to define the self parameter
as <code>using</code> or <code>constexpr</code>.</li>
</ul>
</li>
<li>
<p>As a member, the static keyword can be used to simply make it a free entity that is local to
the owning class.</p>
<ul>
<li>This means there is no self param.</li>
</ul>
</li>
<li>
<p>Operator overloads can be declared as <code>static</code>.</p>
</li>
</ol>
<h2 id="summary"><a class="anchor" name="summary" href="#summary"><span class="octicon octicon-link"></span></a>Summary</h2>
<p>With this we have a facility for writing more idiomatic and concise code with operations on packs all
without polluting the call stack or extraneous type generation. Please consider this language feature
for a future standard of C++.</p>
<p>Thanks for looking at this!</p>
<p>Jason Rice</p>
<h2 id="acknowledgements"><a class="anchor" name="acknowledgements" href="#acknowledgements"><span class="octicon octicon-link"></span></a>Acknowledgements</h2>
<p>Special thanks to Louis Dionne and Miguel Ojeda who provided feedback and suggestions as well as others
who provided feedback on the mailing list.</p>
</div><div id="_toc"><div id="_ul"><a href="#parametric-expressions">Parametric Expressions</a><div id="_ul"><a href="#abstract">Abstract</a><a href="#constexpr-parameters">Constexpr Parameters</a><a href="#using-parameters">Using Parameters</a><a href="#concise-forwarding">Concise Forwarding</a><a href="#operations-on-parameter-packs">Operations on Parameter Packs</a><a href="#friendlier-interfaces">Friendlier Interfaces</a><a href="#as-a-member-of-a-class">As a Member of a Class</a><a href="#transparent-transformations">Transparent Transformations</a><a href="#comparison-with-other-proposed-features">Comparison with Other Proposed Features</a><a href="#notable-concerns">Notable Concerns</a><div id="_ul"><a href="#why-not-go-for-broke-and-jump-straight-into-granular-ast-node-manipulation">Why not go for broke and jump straight into granular AST node manipulation?</a><a href="#invocable-and-the-dangers-of-using-parameters">Invocable and the Dangers of using Parameters</a></div><a href="#impact-on-the-existing-standard">Impact on the Existing Standard</a><a href="#implementation-experience">Implementation Experience</a><a href="#summary">Summary</a><a href="#acknowledgements">Acknowledgements</a></div></div></div></body>
