1 | <HTML> |
---|
2 | <!-- |
---|
3 | -- Copyright (c) Jeremy Siek and Andrew Lumsdaine 2000 |
---|
4 | -- |
---|
5 | -- Permission to use, copy, modify, distribute and sell this software |
---|
6 | -- and its documentation for any purpose is hereby granted without fee, |
---|
7 | -- provided that the above copyright notice appears in all copies and |
---|
8 | -- that both that copyright notice and this permission notice appear |
---|
9 | -- in supporting documentation. We make no |
---|
10 | -- representations about the suitability of this software for any |
---|
11 | -- purpose. It is provided "as is" without express or implied warranty. |
---|
12 | --> |
---|
13 | <Head> |
---|
14 | <Title>Programming With Concepts</Title> |
---|
15 | <BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b" |
---|
16 | ALINK="#ff0000"> |
---|
17 | <IMG SRC="../../boost.png" |
---|
18 | ALT="C++ Boost" width="277" height="86"> |
---|
19 | |
---|
20 | <BR Clear> |
---|
21 | |
---|
22 | <h2><a name="programming-with-concepts">Programming with Concepts</a></h2> |
---|
23 | |
---|
24 | The process of deciding how to group requirements into concepts and |
---|
25 | deciding which concepts to use in each algorithm is perhaps the most |
---|
26 | difficult (yet most important) part of building a generic library. |
---|
27 | A guiding principle to use during this process is one we |
---|
28 | call the <i>requirement minimization principle</i>. |
---|
29 | |
---|
30 | <p> |
---|
31 | <b>Requirement Minimization Principle:</b> Minimize the requirements |
---|
32 | on the input parameters of a component to increase its reusability. |
---|
33 | |
---|
34 | <p> |
---|
35 | There is natural tension in this statement. By definition, the input |
---|
36 | parameters must be used by the component in order for the component to |
---|
37 | accomplish its task (by ``component'' we mean a function or class |
---|
38 | template). The challenge then is to implement the component in such a |
---|
39 | way that makes the fewest assumptions (the minimum requirements) about |
---|
40 | the inputs while still accomplishing the task. |
---|
41 | |
---|
42 | <p> |
---|
43 | The traditional notions of <i>abstraction</i> tie in directly to the |
---|
44 | idea of minimal requirements. The more abstract the input, the fewer |
---|
45 | the requirements. Thus, concepts are simply the embodiment of generic |
---|
46 | abstract data types in C++ template programming. |
---|
47 | |
---|
48 | <p> |
---|
49 | When designing the concepts for some problem domain it is important to |
---|
50 | keep in mind their purpose, namely to express the requirements for the |
---|
51 | input to the components. With respect to the requirement minimization |
---|
52 | principle, this means we want to minimize concepts. |
---|
53 | |
---|
54 | <!-- the following discussion does not match the Standard definition |
---|
55 | of LessThanComparable and needs to be changed -Jeremy |
---|
56 | |
---|
57 | <p> |
---|
58 | It is important to note, however, that |
---|
59 | minimizing concepts does not mean simply |
---|
60 | reducing the number of valid expressions |
---|
61 | in the concept. |
---|
62 | For example, the |
---|
63 | <tt>std::stable_sort()</tt> function requires that the value type of |
---|
64 | the iterator be <a |
---|
65 | href="http://www.sgi.com/tech/stl/LessThanComparable.html"> |
---|
66 | LessThanComparable</a>, which not only |
---|
67 | includes <tt>operator<()</tt>, but also <tt>operator>()</tt>, |
---|
68 | <tt>operator<=()</tt>, and <tt>operator>=()</tt>. |
---|
69 | It turns out that <tt>std::stable_sort()</tt> only uses |
---|
70 | <tt>operator<()</tt>. The question then arises: should |
---|
71 | <tt>std::stable_sort()</tt> be specified in terms of the concept |
---|
72 | <a |
---|
73 | href="http://www.sgi.com/tech/stl/LessThanComparable.html"> |
---|
74 | LessThanComparable</a> or in terms of a concept that only |
---|
75 | requires <tt>operator<()</tt>? |
---|
76 | |
---|
77 | <p> |
---|
78 | We remark first that the use of <a |
---|
79 | href="http://www.sgi.com/tech/stl/LessThanComparable.html"> |
---|
80 | LessThanComparable</a> does not really violate the requirement |
---|
81 | minimization principle because all of the other operators can be |
---|
82 | trivially implemented in terms of <tt>operator<()</tt>. By |
---|
83 | ``trivial'' we mean one line of code and a constant run-time cost. |
---|
84 | More fundamentally, however, the use of <a |
---|
85 | href="http://www.sgi.com/tech/stl/LessThanComparable.html"> |
---|
86 | LessThanComparable</a> does not violate the requirement minimization |
---|
87 | principle because all of the comparison operators (<tt><</tt>, |
---|
88 | <tt>></tt>, <tt><=</tt>, <tt>>=</tt>) are conceptually equivalent (in |
---|
89 | a mathematical sense). Adding conceptually equivalent valid |
---|
90 | expressions is not a violation of the requirement minimization |
---|
91 | principle because no new semantics are being added --- only new |
---|
92 | syntax. The added syntax increases re-usability. |
---|
93 | |
---|
94 | <p> |
---|
95 | For example, |
---|
96 | the |
---|
97 | maintainer of the <tt>std::stable_sort()</tt> may some day change the |
---|
98 | implementation in places to use <tt>operator>()</tt> instead of |
---|
99 | <tt>operator<()</tt>, since, after all, they are equivalent. Since the |
---|
100 | requirements are part of the public interface, such a change could |
---|
101 | potentially break client code. If instead |
---|
102 | <a |
---|
103 | href="http://www.sgi.com/tech/stl/LessThanComparable.html"> |
---|
104 | LessThanComparable</a> is given as the requirement for |
---|
105 | <tt>std::stable_sort()</tt>, then the maintainer is given a reasonable |
---|
106 | amount of flexibility within which to work. |
---|
107 | |
---|
108 | --> |
---|
109 | |
---|
110 | <p> |
---|
111 | Minimality in concepts is a property associated with the underlying |
---|
112 | semantics of the problem domain being represented. In the problem |
---|
113 | domain of basic containers, requiring traversal in a single direction |
---|
114 | is a smaller requirement than requiring traversal in both directions |
---|
115 | (hence the distinction between <a |
---|
116 | href="http://www.sgi.com/tech/stl/ForwardIterator.html"> |
---|
117 | ForwardIterator</a> and |
---|
118 | <a |
---|
119 | href="http://www.sgi.com/tech/stl/BidirectionalIterator.html"> |
---|
120 | BidirectionalIterator</a>). The semantic difference can be easily seen |
---|
121 | in the difference between the set of concrete data structures that |
---|
122 | have forward iterators versus the set that has bidirectional |
---|
123 | iterators. For example, singly-linked lists would fall in the set of |
---|
124 | data structures having forward iterators, but not bidirectional |
---|
125 | iterators. In addition, the set of algorithms that one can implement |
---|
126 | using only forward iterators is quite different than the set that can |
---|
127 | be implemented with bidirectional iterators. Because of this, it is |
---|
128 | important to factor families of requirements into rather fine-grained |
---|
129 | concepts. For example, the requirements for iterators are factored |
---|
130 | into the six STL iterator concepts (trivial, output, input, forward, |
---|
131 | bidirectional, and random access). |
---|
132 | |
---|
133 | <p> |
---|
134 | <a href="./implementation.htm">Next: Implementation</a><br> |
---|
135 | <a href="./concept_covering.htm">Prev: Concept Covering and Archetypes</a> |
---|
136 | |
---|
137 | <br> |
---|
138 | <HR> |
---|
139 | <TABLE> |
---|
140 | <TR valign=top> |
---|
141 | <TD nowrap>Copyright © 2000</TD><TD> |
---|
142 | <A HREF="../../people/jeremy_siek.htm">Jeremy Siek</A>(<A |
---|
143 | HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>) |
---|
144 | Andrew Lumsdaine</A>(<A HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>) |
---|
145 | </TD></TR></TABLE> |
---|
146 | |
---|
147 | </BODY> |
---|
148 | </HTML> |
---|