By now the news has probably reached everyone interested in the evolution of C++0x: the ISO C++ committee voted to remove Concepts from the C++0x working draft at its July 2009 meeting in Frankfurt, Germany. Concepts were the flagship feature of C++0x, and their removal has been met with varying degrees of shock, disappointment and relief. In this post I’ll describe the effort to bring concepts into C++0x and the reasons that effort ultimately failed.
Concepts History
C++ programmers have always wanted a better template programming experience, and the notion of “constraints” for C++ templates go back at least as far as Bjarne Stroustrup’s The Design and Evolution of C++ (see section 15.4). Jeremy Siek and Andrew Lumsdaine extended this notion of constraints checking for “concepts”, and also illustrated how the use of archetypes can mimic type-checking the definition of a template (Siek2000). In 2003, Bjarne Stroustrup and Gabriel Dos Reis brought forward a series of proposals (N1510, N1522, N1536) exploring how concepts could be expressed within the C++ language itself.
My own involvement with concepts began in January of 2005, when I co-authored Concepts for C++0x, which came to be known as the “Indiana” proposal. Shortly afterward, Bjarne Stroustrup and Gabriel Dos Reis proposed A Concept Design (Rev. 1), which came to be known as the “Texas” proposal. Concepts were first discussed in the C++ committee at the April 2005 meeting in Lillehammer, Norway, and it was immediately apparent that the Indiana and Texas proposals were based on fundamentally different philosophies. Although there were several points of contention, the most fundamental disagreement was about the “matching” of a data type to a concept: the Texas proposal favored entirely implicit (automatic) matching (like auto concepts in the current specification), while the Indiana proposal favored an explicit statement of conformance that allowed remapping (like concept maps in the current specification).
Following Lillehammer, I spent much of the next six months implementing ConceptGCC, the first (and only) prototype compiler to implement concepts. The compiler was intended to provide a proof-of-concept, illustrating how a complete system might look within a real compiler. Experience with ConceptGCC helped us produce a drastically improved version of the “Indiana” proposal. I demonstrated ConceptGCC at the October, 2005 meeting. The committee’s reaction was generally favorable, but some members were very concerned by the rapid divergence of the two efforts. The authors were asked to work together to produce a consolidated proposal. We held a number of meetings to hash out the details, and eventually produced the first compromise proposal in June 2006. At the same time, development of ConceptGCC’s standard library continued, and we produced the first proposals to introduce concepts in the standard library (see committee documents N2036-N2041).
We held several meetings outside of the committee, and each new meeting brought more discussions and subsequent changes to the compromise proposal. The largest changes were the removal of “or” constraints, the introduction of scoped concept maps and the elimination of forwarding functions. Also during this time, I completed the first draft of the standard wording for concepts. Many revisions of the wording for both the language and the standard library followed.
Concepts were finally accepted into the C++0x working paper at the September 2008 meeting in San Francisco, and were incorporated into the first C++0x candidate draft (CD1). Overall, they were voted into the C++0x candidate draft as a series of fourteen coordinated proposals, covering the core language and a significant portion of the C++0x standard library.
The Road to Frankfurt
The six or seven months following the San Francisco meeting saw various refinements to the standard wording and standard library. As the Frankfurt meeting neared, two separate issues arose: concerns about implementation experience surfaced and the compromise that produced the concepts specification started to unravel.
The concerns about implementation experience focused on the inadequacies of ConceptGCC, such as its poor compile-time performance and its lack of some advanced features (e.g., scoped concept maps, associated templates). Committee members worried that, without a production-quality implementation to validate the full concepts-based standard library, there would be a significant number of defects in the concepts specification for the language and the library. At best, these defects would further delay the C++0x standard; at worst, we would ship a broken standard.
At the same time, there were numerous, heated discussions of concepts on the committee mailing lists. Most of the heat focused on a single perceived usability problem with the current specification: that, in some cases, users may have to write an “empty” concept map to satisfy the requirements of a constrained template in a library, and that users might view such a concept map as pure syntactic baggage. The discussions revolved around Bjarne Stroustrup’s paper “Simplifying the use of concepts.” Along with creating a general sense of unease about the design, these discussions illustrated plainly how fundamentally different the Indiana and Texas philosophies still were. In particular, Dr. Stroustrup’s paper proposed the elimination of so-called “explicit” concepts, which have been a fundamental part of concepts since 2005 and had been a particularly contentious issue from the beginning.
The Vote in Frankfurt
The C++ committee spent roughly half a day discussing the fate of concepts at the beginning of the Frankfurt meeting. Dr. Stroustrup requested a vote on the following three options:
- Continue with the current specification of concepts in C++0x.
- Make the changes suggested in “Simplifying the use of concepts” and retain concepts in C++0x.
- Remove concepts from C++0x.
Along with an overwhelming majority of committee members, I voted to remove concepts, because I felt that removing them was our best available option both for C++0x and for concepts as a language feature.
My natural inclination would have been to continue with the current specification, which I believe is fundamentally the right design. However, by this point it was clear that our compromise had shattered; we would need to rebuild confidence in concepts before they could be accepted by the wider C++ community. Moreover, the concerns about implementation experience were quite justifiable, and may by themselves have been reason enough to remove concepts from C++0x.
The second option involved making significant changes to the design while still trying to ship concepts as part of C++0x, which I found untenable. Any change of this magnitude coming this late within the development cycle carries significant risk. In this case, there was no implementation experience, no usage experience, and insufficient technical detail to verify that the new design would be functional. Remember that ConceptGCC was already considered by some to be inadequate implementation experience, so there certainly was not enough implementation experience for a modified version of that design. More importantly, I found it extremely unlikely that we would come to consensus on the proposed changes, given the long history of disagreements over this issue.
There were other options, such as delaying C++0x for several more years to allow a consensus to develop, but such delays were considered unacceptable. Removing concepts from C++0x was the only sensible option, and it does not mean that they are gone forever. To the contrary: the committee likes concepts and would consider them again, should a suitable proposal come forward. In my next article, I will discuss some of the lessons we’ve learned from this failure and outline an approach for future work.

Once the “root” concept is explicit, in most cases it doesn’t require any more concept maps even if all of the more-refined concepts are explicit. This is because of the way we tend to use concept maps: we write one concept map for the most specific concept (e.g., RandomAccessIterator rather than Iterator, BackInsertionContainer rather than Container), and the compiler implicitly generates concept maps for the less-specific concepts.
You can actually get this kind of behavior from the current concepts proposal, by using associated requirements rather than refinement. Check out how the OutputIterator concept is specified, which boils down to this:
Here, Iterator is an explicit concept, so you need to write a concept map for it (or one of its more-refined concepts, like RandomAccessIterator) to “opt in” to the iterator system. Then, however, you get the OutputIterator concept automatically matched for your iterator types for any Value type that can be assigned to the reference type of the iterator. I think this gives basically the same capability as the non-auto, non-explicit concepts in your example, and it has definitely come in handy in the Standard Library.
Thanks for coming out to share ideas and comments; it’s great to see different perspectives on a feature like Concepts.
(Quote)I know how much work you and your associates put into Concepts and how disappointing it is when something you have worked on eventually fails to make the cut.
I am sure the decision we reached in Frankfurt was the right one for both C++ and Concepts. And certainly this Sohbet | muhabbet was not a decision to kill Concepts but to give it more time so that we could produce a well honed feature to include in the release of C++ after C++0x.
(Quote)I don’t think the counter-arguments are that strong. There is no dispute that, if a type accidentally matches a given auto concept, it can cause serious problems, such as the InputIterator/ForwardIterator overloading problem described in Explicit Model Definitions are Necessary, where the library ends up performing an incorrect optimization due to an accidental match. The argument against using explicit concepts is that the benefits of less typing (i.e., the elimination of “empty concept maps”) for the user outweigh the dangers of accidental matching. In part, the discussion is so heated because we’re dealing with two properties that are hard to quantify:
How often will users have to write an “empty” concept maps, and will they be viewed as purely syntactic noise?
How often will accidental matches occur, and will these matches result in bugs that require a significant amount of time to find and fix?
Whether you think that a particular concept is explicit or not depends on how you answer those two questions, your tolerance for risk, and so on. From what I’ve seen, people tend to overestimate the number of empty concept maps one needs to write (#1) because they forget the role of concept map templates in the development process. For example, a Graph library like the Boost Graph Library is likely to have graph concepts (e.g., IncidenceGraph) and graph data structures (like adjacency_list) that match those concepts. The author of that library is going to write a concept map template in the library that says that every adjacency_list is an IncidenceGraph, because that concept map template will make sure that the concepts and data structures keep in sync (since concept map templates are fully type-checked), documents for the user that every adjacency_list is an IncidenceGraph (which would otherwise be just a comment somewhere), and eliminates the need for the user to write concept maps in the common case.
Well, we clearly have to do -something- about the InputIterator/ForwardIterator problem I mentioned previously (as well as the RandomAccessIterator/ContiguousIterator problem Stroustrup uses to describe explicit refinement). I’ve seen this same problem show up in most of the other C++ generic libraries I’ve worked on, so it doesn’t seem to be an isolated example. Explicit concepts are one obvious way to solve this problem.
I don’t know whether explicit refinement solves the problem as well as explicit concepts or not. The discussion of explicit refinement on the committee mailing list ran for more than 200 messages, and participants weren’t clear about how explicit refinement really worked. Under some interpretations, it had certain type-safety problems where a type could be a ContiguousIterator in one call but only a RandomAccessIterator in another call. Under other interpretations, explicit refinement was just an alternative syntax with the same semantics as explicit concepts. Without a more detailed specification, we can’t really meaningfully evaluate explicit refinement: there are just too many open questions.
(Quote)Hi Doug. Thanks for your answer.
In my opinion explicit refinement -can’t- replace explicit concepts.
As I understand it, explicit refinement forbids inheritance-like implicit matching. This works for things like iterator (iterator is auto, but walking down the refinement tree can be limited in certain points). On the other hand, explicit concepts can prevent implicit matching of the root too.
I think of this mechanism:
Explicit concepts (or explicit refinement) could be used to make some inner nodes unreacheable unless stated otherwise. All auto-nodes can be reached if the parents can be reached.
(Quote)this thing ate my code see it here: http://zone-team.com.mx/temp/c.cpp
(Quote)Rodrigo, I think I went in and fixed the code up; does that look better? I’ll try to track down this bug. Sorry for the inconvenience.
(Quote)Explicit concepts do not prevent implicit matching of more-specific auto concepts, so the last two lines of your example should read:
The “Indiana” group discussed similar examples back in 2005, and we decided that “auto” should really mean “auto”: if you match the syntax of an auto concept, it works even if there is an explicit concept as a root. ConceptGCC actually had this wrong (it’s fixed now), but the specification is clear.
The net effect of this behavior is that you can actually turn any explicit concept “C” into an auto concept with a little trick:
Hi Doug.
I see. I think the optimal solution may be somewhere between, but it seems it starts getting more complicated (at least without a whole redesign). Thanks for your reply.
And thanks to Dave for fixing my code!
(Quote)Hi Rodrigo,
The question is, in between what and what? It’s very easy to say that the right answer probably lies between two competing points of view, but the proposal that was voted into the WP already has optional implicit matching (auto concepts).
(Quote)Yes, its easy to say that but that’s why I didn’t attempt to criticize Indiana’s design (ID) more deeply.
I consider ID more convenient than TD. In fact, my full opposition to the “nothing-is-explicit” or the “explicit-refinement-only” alternatives is because they are subsets of the ID in terms of power.
However, I really hate the number of explicit concepts the ID tends to generate. I find the fact that BackInsertionContainer and friends are explicit embarassing considering they are refinements of another explicit concept: Container. If a type is explicitly told to be a Container, they should be able to automatically match the mentioned refinements. If the types are’t Containers, they shouldn’t.
Doug came with a rationale on why it wasn’t this way. My opinion is that it was a wrong decision. Other options may exist. For example, we could have: concept, auto concept, explicit concept. http://zone-team.com.mx/temp/c2.cpp summarizes my thoughts.
The optimal solution is between “too much explicit” and “explicit enough”. And no, TD isn’t “explicit enough”. ID is closer to that lower bound than TD is.
(Quote)Hi Doug -
Thanks for the article explaining the history of concepts. Also, thanks for all the hard work you, Jeremy, Dave, Andrew and everyone else have done building concepts. Finally, thanks for building a real implementation in ConceptGCC (which I’ve used). =)
I’m disappointed that concepts have been removed from C++0x. From the little that I know about concepts, it seems like they are one of those rare gems that do a number of things right. They reduce the complexity of compiler errors; they make C++ code more maintainable (preconditions are programmatically documented); they increase the strength of template contracts; they reduce the complexity of template use; and increase the robustness and correctness of template implementation.
Losing concepts is particularly frustrating to me because it was one of the features that I’ve been touting to anti-C++ programmers as a “tool to simplify things”. It’s no secret, many people think C++ is too complex. While I agree with many of the hardcore C++ programmers that C++’s complexity is necessary for its performance, I also think we need to simplify things for “new-to-C++” programmers. That’s why losing concepts from C++0x is so painful: concepts simplify the usage of templates by a huge margin which certainly eases the introduction into templates for new programmers.
Gaining new C++ programmers is obviously important to a lot of people, including Stroustrup, since his latest book is specifically geared toward new programmers (http://www.research.att.com/~bs/programming.html).
Whatever the case, I appreciate the professionalism of your article and your dedication to the future of concepts and C++ in general. Please don’t stop doing what you’re doing: C++ needs you and your concepts.
(Quote)Hi Dave and Doug!
In my opinion the current design was ok (but not perfect, member-function matching and so on). However I think the problem appeared when the conceptualization of the library started to include -too many- explicit concepts. Under that light I agree with Stroustrup; most if not almost all library concepts should remain automatic since, if we struggle hard enough, its easy to find counter-arguments against the auto-matching for every single concept we may think of.
The conceptualization of the standard library probably doesn’t need any explicit concepts (explicit refinement as Stroustrup calls it could solve those special cases). But getting rid of explicit concepts completely, as I see it, was an extreme alternative.
(Quote)I’m glad there are experts debating things and that the committee did not settle for the sake of settling. One of C++’s strongest points is the scrutiny everything gets to enable efficient code, ease of use, etc…This is fortunate for me, as I do not have the where-with-all to do this, however I get the benefits of programming in C++…
One thing that has been lingering in my mind for a long time, and maybe this is another indication of it, is that template are incredibly powerful, yet they seem clumsy in many circumstances. Is it time to take all the experiences learned from templates, generic programming, etc and specify a new language component that replaces/complements the preprocessor and templates? It seems one could integrate concepts, template meta-programming, provide better error messages, etc. I have no idea what it would look like, just my $0.02…
Thanks again for everyone’s hard work making C++ great.
(Quote)@Brian: I know I speak for everyone on the committee when I thank you for your kind words. I consider it a privilege to be able to contribute to the C++ community.
About clumsy templates, I agree: they’re not a perfect match for many things we use them for. It may be time to specify a new language component, or maybe a new language. I have vague ideas about what some of that could look like, but nothing solid enough to post about in public
. Let us know if you come up with something!
(Quote)Interesting read. My impression so far is that most C++ developers are pretty accepting of the decision. Of course everyone would've liked to see a good implementation of Concepts, but there seems to be a broad understanding of why it wasn't viable in C++0x.
Personally, I lean strongly towards the "Texas" philosophy. Concepts should never be a burden to use. If they require the programmer to jump through hoops that weren't necessary in C++03, you risk alienating users who might either draw back from generic programming in general (which would be bad), or stick with C++03 even after 0x is released (which would be worse).
One of the most important factors in the popularity of the STL and generic programming in general, is that , well, it is generic. A container or algorithm is hardly very generic if it requires the user's type to explicitly state support for it.
And legacy codebases don't exactly help either. You'll have users who have huge C++ codebases where not a single type implements a concept. If this code is not compatible with new language or library features which require explicit concept maps, it seems likely that the codebase will just stick with C++03.
Of course I'm just a casual observer following some of the C++0x progress out of interest. You've probably considered all the above many times before and I'm sure there are good reasons for the "Indiana" philosophy as well. But ultimately, I think usability and the ability to just "work out of the box" even with legacy code, must trump all other concerns. The original motivation for concepts was to ease programming for users after all.
Anyway, as said above, I too am excited about C++'s future. And the decision to drop concepts (for now) has, imo, only underlined that you guys are willing and able to take tough decisions when you have to. If anything, it has given me a lot more faith in the quality of C++0x when it is finalized.
(Quote)@Jesper, a few brief points:
First, an explicit declaration of conformance is not about matching up a single type with a single container or algorithm. That would indeed be impossibly burdensome. It’s about matching up a type (or set of types, in the case of concept map templates) with a concept that is used as a constraint over many components.
Second, that concepts should never be a burden to use, nor should they require the programmer to jump through hoops that weren’t necessary in C++03, is like “motherhood and apple pie.” Everyone agrees on that. That conforming C++03 code should continue to compile without modification in a conceptified C++ is likewise agreed upon. [*]
Third, however, everyone also agrees that a significant amount of C++03 code will require modification to work in a concept-constrained world, because so many uses of the standard library that “just work” today simply don’t conform to all the stated requirements that, under a concept-enabled library, would be fully syntactically checked (“oops, your “input iterator” omits a postincrement operator!”)
In the end, some — probably many — programmers are going to be “burdened” and feel as though they’re “jumping through hoops” when the code that seems perfectly good today stops compiling. So ask yourself, do you really want these constraints at all? What is the value to the programmer of requiring more than the absolute minimum mandated by the implementation of an algorithm or component? I know my answer; what’s yours?
[*] Doug’s statement that the Indiana philosophy “favors” an explicit declaration of performance is really only true by comparison to the Texas philosophy. The Indiana crew always knew we would need something like auto concepts, but were clear from the start that explicit conformance was fundamental and thus chose it as a starting point for their design. The ability of concept authors to choose between automatic and explicit conformance seemed to have consensus until about a week before Frankfurt.
(Quote)@Jesper: in addition, please allow me to welcome you to C++Next and thank you for your comments. That sort of perspective and constructive input is exactly what we had in mind when we started this site.
(Quote)Nice summary and helpful historical review. I, too, appreciate your efforts in trying to bring Concepts to C++0x. It is a necessary addition. (I also appreciate all of your involvement in C++ standardization, Boost, and GCC.)
I don't know enough details to judge between the Indiana and Texas proposals, but Bjarne's Simplifying doc is compelling on the surface. That is, I think it is far better when types "just work" if that can be done. If that leads to enough ambiguities or other difficulties that force one to typically be explicit anyway, then always being explicit may be justified. Such an opinion is probably not worth much to you, but I offer it in the hopes that it will be somehow beneficial to the discussions.
My work involves writing cross-platform code, so I would be hard pressed to do much with Concepts until they were standardized and my compilers all supported the same functionality. Others at my company have more latitude and might be able to make use of them sooner. I will certainly encourage that where it makes sense.
(Quote)Quick clarification—nobody was ever in favor of always being explicit. See my reply to Jesper, and stay tuned for an article or two about the different kinds of concepts and concept maps. I think they will help fill in the details.
(Quote)This website is a really good idea. I enjoyed the history, and will have to read through the evolution of proposals at some point. I’m looking forward to the future of concepts in C++. I think this is another great opportunity for them, and this time I have a chance to be involved.
(Quote)I wish your clang will be the first compiler which implements concepts fully! (Of course without the standard it’s hard to say what is meant by “fully”…) Do you have any time frame when that might happen?
(Quote)There are no time frames for Clang, by project policy. We’re currently in the middle of C++03 support (CodeGen is making huge progress, from what I’ve seen on my commits backlog), and we’ve been there for about half a year. A reasonable guess at the time it takes to bring it to a really usable state is anywhere from 6 to 24 months. (I really hope it’s closer to the former.) That doesn’t say anything about concepts, of course. However, bear in mind that once we’re done with C++03, we’ve still got a C++0x standard to implement, which is a higher priority than possible C++1x features.
(Quote)Thank you very much for your herculean efforts in the design of concepts and making them tangible by providing the only implementation. Also thank you for all the other features in C++0x that you’ve either pioneered or contributed to. And while I do not have license to speak for the entire C++ community, I doubt anyone would disagree when I say that we are greatly indebted to your efforts.
There has been a lot of negative press about C++ recently (http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=443, http://lambda-the-ultimate.org/node/3518#comment-50099) – and while I agree with a small portion of the criticism (especially regarding the lack of first-class reflective/introspective features) – much of it seems like unjustified flailing speculation (“C++0x is the next C99″) based on insufficient evidence (in my opinion).
So thank you for this post and this website and for influencing and providing an important space for C++ (language/standard-related) discussions on the Web.
I am excited about C++’s future – I have been following the standardization process and am quite confident that the next revision of C++ will be much more fun to program in – and I personally can’t wait to participate in and witness the evolution of ‘C++ Concepts’.
Thanks!
(Quote)Thank you for nice article. I’m really sad about removal of concept.
Translated to Japanese. http://cpplover.blogspot.com/2009/08/douglas-gregor.html
(Quote)Thanks Doug for a very fair presentation of the history. I know how much work you and your associates put into Concepts and how disappointing it is when something you have worked on eventually fails to make the cut.
I am sure the decision we reached in Frankfurt was the right one for both C++ and Concepts. And certainly this was not a decision to kill Concepts but to give it more time so that we could produce a well honed feature to include in the release of C++ after C++0x.
(Quote)It’s really nice to have some behind the scenes information about what’s going on with C++ 0x. This is really a great post.
I love concepts and the ideas behind them, and to me, it’s clearly a step in the right direction of writing correct and efficient program using template meta-programming techniques. I work a lot on cryptography and software security, you can guess that I do everything I can to put as much validation as early as possible.
My goal would be to have bugs to prevent compilation. However what’s really important is to keep the language moving forward.
I know I have been eagerly looking forward an updated revision of the C++ standard as I struggle everyday with inconveniences of the language soon to be alleviated. I’m immediately thinking about lambdas, auto, static_assert, variadic templates, etc.
What I mean by that is that even without concepts the new standard will make my life better!
I’m pretty sure that the people behind concepts will be able to think on it with less pressure now that 0x is wrapped up. I also think that the feedback from the novelties released in 0x will even help them reconsider their positions in terms of implementation complexity and interest of use.
Also don’t forget that from a pragmatic point of view, the differences between the Indiana approach and the Texas approach… Well… I’m sorry to say that I cannot manage to care. Just choose one and I’ll use it.
Keep in mind the pragmatic programmers when you debate over the benefits of one doctrine versus the other…
(Quote)Pragmatic programmers are (and have always been) at the center of the debate between the two approaches. Proponents of the different concepts philosophies have different views on how everyday programmers will (or should) use concepts, which led to the divergence between the the approaches. What was missing from these discussions was the input of everyday programmers: we lacked enough usage experience with concepts to determine whether potential problems would affect real-world code, or how often these problems would occur. Early usage experience with ConceptGCC was extremely helpful in honing the Indiana proposal, and a major theme of my follow-up article on concepts will revolve around the need for better concepts implementations used by a wider range of programmers.
(Quote)I didn’t mean to imply that you weren’t pragmatic.
That’s a problem we face everyday. When adding a feature into a program, if you don’t have feedback it’s just a question of gut feeling. “I think people would do that way…” Actually nobody knows until the program is launched in the wild.
That reminds me the series of article about how they used the input of users collected during years (you know the “send anonymous data to Microsoft to help improve the program” dialogue box that pops out? that’s what it’s used for) to redesign Office 2007 (http://blogs.msdn.com/jensenh/archive/tags/All+Office+2007+UI+Posts/default.aspx).
For example knowing what are the 5 most used commands in your program is extremely helpful in avoiding heated debated and designing an efficient UI (http://blogs.msdn.com/jensenh/archive/2006/04/07/570798.aspx).
If you could somehow gather a lot of data about how people use concepts, that would certainly be extremely useful. Maybe embedding something into the compiler that would send some anonymous statistics to a central server?
Don’t know if that makes sense in this context.
(Quote)It’s pretty hard to bootstrap significant usage experience for a language feature as big as concepts. Compiler vendors are generally not eager to invest resources in implementation until the feature is very likely to be standardized. Users are generally not eager to use non-standard language features in production code, especially without many implementations out there to reduce the risk of vendor tie-in. So while it would be great to gather lots of data, I wouldn’t expect to be able to find that data much before the language feature is at least blessed by a TR.
(Quote)I’m a bit disapointed – like many i assume – to see this. What are the tim frame for mulling over concepts again ?
(Quote)There is no schedule for work on concepts. It’s unlikely that there will be another chance to actually standardize concepts for at least five years, perhaps more. However, for a concepts effort to succeed by then it will need to get started within the next year or two so that we can develop enough implementation and usage experience to be confident in the design. I’ll try to cover this, too, in my follow-up article.
(Quote)Thanks for this informative description! I’m really looking forward to future articles
(Quote)