<!DOCTYPE html>
<html lang="en"><head>
   <style>
/**
 * SyntaxHighlighter
 * http://alexgorbatchev.com/SyntaxHighlighter
 *
 * SyntaxHighlighter is donationware. If you are using it, please donate.
 * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
 *
 * @version
 * 3.0.83 (July 02 2010)
 * 
 * @copyright
 * Copyright (C) 2004-2010 Alex Gorbatchev.
 *
 * @license
 * Dual licensed under the MIT and GPL licenses.
 */
.syntaxhighlighter {
  background-color: white !important;
}
.syntaxhighlighter .line.alt1 {
  background-color: white !important;
}
.syntaxhighlighter .line.alt2 {
  background-color: white !important;
}
.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
  background-color: #e0e0e0 !important;
}
.syntaxhighlighter .line.highlighted.number {
  color: black !important;
}
.syntaxhighlighter table caption {
  color: black !important;
}
.syntaxhighlighter .gutter {
  color: #afafaf !important;
}
.syntaxhighlighter .gutter .line {
  border-right: 3px solid #6ce26c !important;
}
.syntaxhighlighter .gutter .line.highlighted {
  background-color: #6ce26c !important;
  color: white !important;
}
.syntaxhighlighter.printing .line .content {
  border: none !important;
}
.syntaxhighlighter.collapsed {
  overflow: visible !important;
}
.syntaxhighlighter.collapsed .toolbar {
  color: blue !important;
  background: white !important;
  border: 1px solid #6ce26c !important;
}
.syntaxhighlighter.collapsed .toolbar a {
  color: blue !important;
}
.syntaxhighlighter.collapsed .toolbar a:hover {
  color: red !important;
}
.syntaxhighlighter .toolbar {
  color: white !important;
  background: #6ce26c !important;
  border: none !important;
}
.syntaxhighlighter .toolbar a {
  color: white !important;
}
.syntaxhighlighter .toolbar a:hover {
  color: black !important;
}
.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
  color: black !important;
}
.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
  color: #008200 !important;
}
.syntaxhighlighter .string, .syntaxhighlighter .string a {
  color: blue !important;
}
.syntaxhighlighter .keyword {
  color: #006699 !important;
}
.syntaxhighlighter .preprocessor {
  color: gray !important;
}
.syntaxhighlighter .variable {
  color: #aa7700 !important;
}
.syntaxhighlighter .value {
  color: #009900 !important;
}
.syntaxhighlighter .functions {
  color: #ff1493 !important;
}
.syntaxhighlighter .constants {
  color: #0066cc !important;
}
.syntaxhighlighter .script {
  font-weight: bold !important;
  color: #006699 !important;
  background-color: none !important;
}
.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
  color: gray !important;
}
.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
  color: #ff1493 !important;
}
.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
  color: red !important;
}

.syntaxhighlighter .keyword {
  font-weight: bold !important;
}
.syntaxhighlighter div.toolbar span a.toolbar_item{
   display: none !important;
} 
body .syntaxhighlighter .line {
    white-space: pre !important;
}
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.kwd,.tag,.typ{font-weight:700}.str{color:#060}.kwd{color:#006}.com{color:#600;font-style:italic}.typ{color:#404}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
    </style>
<title>A simple proposal for unifying generic and object-oriented programming</title>
</head>

<body>
<p>P1199R0<br>
Mike Spertus, Symantec<br>
<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br>
2018-08-10<br>
Audience: Evolution Working Group
</p>
	
	<h1>A simple proposal for unifying generic and object-oriented programming</h1> 
	<p>In this paper, we propose a simple extension to <a href="http://wg21.link/p1141r1">P1141R1</a>
	that we believe provides a simple and comprehensive proposal for unifying generic and object-oriented programming.</p>
	<h2>The problem</h2>
	C++ works best when compile-time and run-time programming are similar. For example, <tt>constexpr</tt> functions allow programs to easily move calculations back and forth between compile-time and run-time as circumstances dictate with no change in code. Likewise, it is well-known that generic programming and object-oriented programming can be applied to similar problems (e.g., Bjarne Stroustrup's <a href="http://www.cs.ox.ac.uk/ralf.hinze/WG2.8/28/slides/bjarne.pdf">Concepts for C++1y: The Challenge</a>), but they do so with very different notations. 
    Once the design decision is made about whether to use templates
	or virtual functions, it is extremely committal and cannot easily be changed.
	<p>For example, in designing a drawing library, one would need to decide whether to provide distinct shapes
        via a <tt>Shape</tt> base class providing runtime dispatch with virtual
	functions or a <tt>Shape</tt> concept providing compile-time dispatch.
        If <tt>Shape</tt> is a class, a function might be declared as</p>
	<blockquote><div><div id="highlighter_882026" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s);</code></div></div></td></tr></tbody></table></div></div></blockquote>
However, it <tt>Shape</tt> is a concept, a very different declaration must be used:
	<blockquote><div><div id="highlighter_738651" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code><code class="cpp plain">&lt;</code><code class="cpp keyword bold">typename</code> <code class="cpp plain">T&gt; requires Shape&lt;T&gt; </code><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(T </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s);</code></div></div></td></tr></tbody></table></div></div></blockquote>
Once this choice is made, the programmer is fully committed to one of two very different programming
    paradigms with complex tradeoffs from day one.

	<p>Terse notation, as proposed most recently in P1141R1, reduces the notational gap between object-oriented and template programming:
    </p><blockquote><div><div id="highlighter_910118" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s);</code></div></div></td></tr></tbody></table></div></div></blockquote>
	However, switching <tt>Shape</tt> between a class and a concept still requires changing the 
    declaration of <tt>is_convex</tt>, and even if the declaration were the same (as in the 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4377.pdf">Concepts TS</a>),
    many changes would undoubtedly need to be made to the function body to accommodate changing
    <tt>Shape</tt> from a class to a concept. E.g., <blockquote><div><div id="highlighter_852403" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// Body is ok if Shape is a class but badly broken if Shape is a concept</code></div><div class="line number2 index1 alt1"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s) </code></div><div class="line number3 index2 alt2"><code class="cpp plain">{</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">pair&lt;Shape, </code><code class="cpp color1 bold">int</code><code class="cpp plain">&gt; p(s, 7);</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">auto x = make_unique&lt;optional&lt;Shape&gt;&gt;(convex_hull(s));</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp comments">/* ... */</code></div><div class="line number7 index6 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></blockquote>
In the end, the obvious similarity between compile-time and runtime dispatch
sometimes feels more like something that is there to tantalize and frustrate us than something
that can be effectively leveraged.
<h2>Our Solution</h2>
So, how do we create code that works equally well regardless of whether <tt>Shape</tt> is a class
    or a concept? Fortunately,
	 P1141R1 provides <tt>auto</tt> as a sigil that indicates something that looks like a type 
    could be a concept.
	<blockquote><div><div id="highlighter_668144" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// is_convex is a function template</code></div><div class="line number2 index1 alt1"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s) { </code><code class="cpp comments">/* ... */</code> <code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></blockquote>
	
P1141R1 defines what this means when <tt>Shape</tt> is a concept. If we want this code
    to work regardless of whether <tt>Shape</tt> is a concept or a class, we 
	need to define what it means when <tt>Shape</tt> is a class:

<p>First, we introduce one notation. It <code><em>C</em></code> is a class, we let
    <tt>inherits_from_<em>C</em>&lt;T&gt;</tt> denote the concept asserting that <tt>T</tt> publicly
    inherits from <tt>C</tt>.
    For example, if <tt>Shape</tt> is a class, then <tt>inherits_from_Shape</tt> is the concept
    </p><blockquote><div><div id="highlighter_718432" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp keyword bold">template</code><code class="cpp plain">&lt;</code><code class="cpp keyword bold">typename</code> <code class="cpp plain">T&gt; concept </code><code class="cpp color1 bold">bool</code> <code class="cpp plain">inherits_from_Shape = is_convertible_v&lt;T *, Shape *&gt;;</code></div></div></td></tr></tbody></table></div></div></blockquote>
Now we can state our proposal simply as:
<h3>Proposal</h3>
With the above notation, we propose everything as in P1141R1 with the additional rules that if <tt>C</tt>
is a class,
<ul><li>Occurrences of <tt>C auto</tt> are replaced by <tt>inherits_from_C auto</tt>.</li>
<li>Implicit conversions</li>
<li>If a function template has a <tt>C auto</tt> in its parameter list, any occurrences of <tt>C</tt> within the function body are also replaced by <tt>inherits_from_C auto</tt></li>
</ul>
That's it! Let's make it concrete illustrative examples
<h3>Illustrative examples</h3>
As noted above, P1141R1 explains what
<blockquote><div><div id="highlighter_817430" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s);</code></div></div></td></tr></tbody></table></div></div></blockquote>
means if <tt>Shape</tt> is a concept. What we propose is that if 
<tt>Shape</tt> is a class, then the above is rewritten as
<blockquote><div><div id="highlighter_17848" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(inherits_from_Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s);</code></div></div></td></tr></tbody></table></div></div></blockquote>
In this way, we ensure that the declaration of <tt>is_convex</tt> makes sense
regardless of whether <tt>Shape</tt> is a class or a concept. Furthermore, since
all occurrences of <tt>Shape</tt> within the body of <tt>is_convex</tt> are also
replaced by the <tt>inherits_from_Shape</tt> concept, all of the subtle distinctions
between classes and concepts are mooted, and we don't need to worry that we will create
brittle code that inadvertently assumes that <tt>Shape</tt> is a class.
<p>We illustrate this ease of writing flexible function bodies with another example
</p><blockquote><div><div id="highlighter_652160" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// Want to work identically whether Shape is a concept or type</code></div><div class="line number2 index1 alt1"><code class="cpp color1 bold">bool</code> <code class="cpp plain">sameShapeMaybeDifferentPosition(Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s1, Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s2) {&nbsp;&nbsp; </code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s1Translated = s1 – s1.lower_left();</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s2Translated = s2 – s2.lower_left();</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">sameShape(s1Translated, s2Translated);</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></blockquote>
To see that this code works the same way whether <tt>Shape</tt> is a class or concept,
let us examine both cases
<h4><tt>Shape</tt> is a concept</h4>
In this case, it means exactly what it does in P1141R1: A concept-constrained function template.
We note particular that, by independent binding, <tt>s1</tt> and <tt>s2</tt> may
have different types, such as <tt>triangle</tt> and <tt>ellipse</tt>.
<h4><tt>Shape</tt> is a class</h4>
On the other hand, if <tt>Shape</tt> is now a class with virtual functions that
    are implemented by derived classes <tt>Triangle</tt> and <tt>Ellipse</tt>,
    the above function still works without changes. In this case, the compiler reinterprets it as
<blockquote><div><div id="highlighter_799145" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// Want to work identically whether Shape is a concept or type</code></div><div class="line number2 index1 alt1"><code class="cpp color1 bold">bool</code> <code class="cpp plain">sameShapeMaybeDifferentPosition(inherits_from_Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s1, inherits_from_Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s2) {&nbsp;&nbsp; </code></div><div class="line number3 index2 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">inherits_from_Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s1Translated = s1 – s1.lower_left();</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp plain">inherits_from_Shape </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s2Translated = s2 – s2.lower_left();</code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;&nbsp;</code><code class="cpp keyword bold">return</code> <code class="cpp plain">sameShape(s1Translated, s2Translated);</code></div><div class="line number6 index5 alt1"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></blockquote>

so if it is called, for example, with two <tt>Shape &amp;</tt> arguments, instead of
doing compile-time dispatch as it did with the above example, it does runtime dispatch with virtual 
function dispatch.
We note again that because the objects' runtime types may differ, that this correctly corresponds 
to the independent binding of the concepts version above.
<h4>Changing <tt>Shape</tt> between a class and a concept</h4>
As we see from the above example, <tt>Shape</tt> can be changed back and forth
between a class and a concept during tuning and as needs evolve in the future,
replacing a brittle, premature, and commital decision with robust and flexible
code that works equally well with object-orientation and generics.

<h2>The role of inferencing</h2>
Looking at the body for <tt>is_convex</tt> at the top of this
paper, we see that the code implicitly assumes that <tt>Shape</tt> is 
a class in many places. While the above proposal ensures that classes
that may be replaced with concepts later will not be able to use such code,
that may be perceived as too high a price if programming with concepts is
much more difficult than programming with classes. Indeed, irrespective of this proposal,
Bjarne Stroustrup and others have likewise noted that for concepts to reach its full potential,
code written with concepts 
need not be much harder than programming with types and that safe and easy constrained inferencing
is key to that.
<p>So how should the body of <tt>is_convex</tt> have been written? As the reader
might guess, constrained inferencing as provided by P1141R1 and robust class template argument
deduction are the key.</p>
<blockquote><div><div id="highlighter_569056" class="syntaxhighlighter nogutter  cpp"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cpp comments">// The following is now ok regardless of whether Shape is a class or a concept</code></div><div class="line number2 index1 alt1"><code class="cpp color1 bold">bool</code> <code class="cpp plain">is_convex(Shape auto </code><code class="cpp keyword bold">const</code> <code class="cpp plain">&amp;s) </code></div><div class="line number3 index2 alt2"><code class="cpp plain">{</code></div><div class="line number4 index3 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">pair p(s, 7); </code></div><div class="line number5 index4 alt2"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp plain">auto x = make_unique&lt;optional&gt;(convex_hull(s)); </code><code class="cpp comments">// Assumes P1069R0</code></div><div class="line number6 index5 alt1"><code class="cpp spaces">&nbsp;&nbsp;</code><code class="cpp comments">/* ... */</code></div><div class="line number7 index6 alt2"><code class="cpp plain">}</code></div></div></td></tr></tbody></table></div></div></blockquote>
In fact, we would go so far as to say that the code is clearer, more robust, and flexible
than the original class-based code (We understand that contrary examples can be constructed,
but that does not detract from the value of writing code that is agnostic between classes
and concepts).
    <p>Indeed, we would go even further to say that constrained inferencing
as provided by concepts and class template argument deduction is key to writing flexible 
scalable code, one of the most important problems in programming. As has long been known, unconstrained generic code is very flexible
but is difficult to scale as millions of lines of unconstrained types will leave the 
    programmer thoroughly perplexed (this is of course one of the main problems
    concepts was designed to solve). On the other hand, code written with explicit
    types is clear, but also fails to scale as it does not separate an object's implementation
    from the way it is used, resulting in tight coupling where changing the type of
    an object to a different class with the same external behavior can require thousands
    of changes scattered through the code. As a result, large programs become brittle
    and difficult to evolve over time and successive releases can no longer provide rapid
    improvement (or often, any meaningful improvement at all).
</p><p>We believe that with safe and easy constrained inferencing, loose coupling can be maintained, and writing
code to work for both classes and concepts as described in this paper will result in it being enhanced
    rather than compromised. See <a href="http://wg21.link/p1168r0">P1168R0</a> for a more
    detailed look with concrete examples at how robust constrained inferencing terse 
    notation and class template argument deduction can enable flexible, readable, and scalable code.
</p><h2>Conclusion</h2>
By building on P1141R1 to allow <tt><em>classname</em> auto</tt> according to the above rules, writing code that flexibly works with both classes and concepts becomes as
easy as writing concepts code alone, providing a simple unification between the two major programming styles in C++, without the need to
get mired in the myriad subtle differences between generic
and object-oriented programming.

</body></html>