<div class="gmail_quote">On Sat, Jul 30, 2011 at 6:31 PM, Howard Hinnant <span dir="ltr"><<a href="mailto:hhinnant@apple.com">hhinnant@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
In existing C++03 standard libraries there are a ton of extensions.  Some good, some not so good.  Some of the better ones have morphed into official  C++11 libraries.  However, I can't think of a single example where an extension has been standardized unchanged from its extension form.  There is good reason for this.<br>

<br>
I'm going to pick on slist.  But my argument is meant to be broader than slist.<br></blockquote><div><br></div><div><snip></div><div><br></div><div>I want to clarify, I don't disagree with *any* of your diagnosis. I agree completely with the flaws and problems present in slist.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">When our customers are migrating to libc++, it is at a time of their choosing.  They have set aside time to do the migration.  And shown interest in doing so.  A year after they migrate, when subtle problems surface, they are not going to be in the mood to be educated.  They are going to be in the mood to be educated about the right way to do things *when they are migrating*, and not later when run time problems arise.<br>
</blockquote><div><br></div><div>Keep in mind that some customers at least may not be able to update all of their code in one fell swoop. Forcing changes to the client code in too many places may make it impossible to migrate at all rather than merely adding to the cost of migration.</div>
<div><br></div><div>Also, in some contexts, there is no user education to be done. The code in question is legacy code, old and slated for deletion. No one maintains it, updates it, or cares for it; but it isn't (quite) ready to be removed once and for all. These situations make the arguments about education only apply to a subset of the migration (although there they certainly make sense).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">1.  We could create an ext::slist that lacks size().  That way the customer would not have to change their code unless they used size().<br>
</blockquote><div><br></div><div>I agree with your disadvantages here. Reducing (slightly) the magnitude of those changes doesn't seem as attractive. For a significant chunk of the code I've seen in this position, the cost of changing the code is dominated by a very high constant factor, not by the nature of the change itself. (Consider, an open source library that has to have changes pushed back upstream, and written in a particular style and which no one is actively maintaining any longer.)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">2.  Status quo:  We could do nothing.<br>
<br>
Disadvantage:  I'm seeing rising complaints about migration efforts.<br></blockquote><div><br></div><div>There is another disadvantage: it may preclude migration at all. If there exists code that simply can't be updated, you're now stuck.</div>
<div><br></div><div>More realistically, it may drive the cost of migration sufficiently far up that it becomes a difficult or impossible to tackle problem.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
3.  Educate:  In a private email about a week ago M.E. O'Neill noted that we should provide documentation recommending migration strategies for things like slist -> forward_list.  She suggested actually providing an <slist> header which did nothing but point to the documentation and then error out.  I'm not sure I'd go as far as providing such a header.  But I am really enthusiastic about a "migration document".  Having something to point to which explains why using slist is like playing with a loaded gun.  When people are migrating, they are open to such arguments if those arguments are both convincing and readily available.  And if the migration document provides a way to experiment without committing yourself (i.e. make it easy to backpedal the migration):<br>
</blockquote><div><br></div><div>Again, see my points above about education. Sometimes there is no one to educate, and no one intending to maintain or improve the code long term. Certainly, documenting the migration hurdles is very helpful to those doing the migration, but it may not be enough for sufficiently popular extensions.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Disadvantage:  Doesn't provide seamless migration.  And it is a fair amount of work to document.<br>
<br>
Field experience:  I'm responsible for deprecating auto_ptr.  At the same time I introduced unique_ptr.  This involved a lot of documentation.  Not only with committee papers, but in participating in countless newsgroup and mailing posts to the general public, presentations, etc.  And it is paying off.  I now see lots of people I've never heard of telling others that they should replace auto_ptr with unique_ptr, even though it is not a drop-in replacement.  And the listeners are receptive to the message.<br>
</blockquote><div><br></div><div>I don't really dispute any part of this other than the value of education on old code. For new code and actively maintained code, this is all spot on.</div><div><br></div><div>That said, I would like to migrate a very large codebase to a point where it could use libc++. Why? Because I want to migrate the codebase to C++0x, and one aspect of doing that is migrating to a viable standard library for C++0x. I'm very interested in investigating the trade-offs between libstdc++ and libc++ here, but we can't do that if we have to update the entire code base in the process.</div>
<div><br></div><div>I actually will pick on hash_{map,set} here because I think they're even better examples. I actually agree that 'slist' is border-line.</div><div><br></div><div>There is essentially zero possibility that we will use hash_map forever. We will switch to unordered_map because its better and because its standardized. However, it isn't available (technically[1]) until we switch to C++0x. With a codebase of sufficiently large size, we can't afford to do both transitions simultaneously, we have to first switch to C++0x, and then switch from old extension containers to new standard ones.</div>
<div><br></div><div>[1]: Yes it is available as std::tr1::unordered_map, but now we have to migrate the codebase 3 times, once to the std::tr1 implementation, once to 0x, and then once back to std::. That drives up the cost of migration by another notch.</div>
<div><br></div><div>Now, my goal is to have two different libraries to choose from when migrating to C++0x so that bugs in one don't block progress. But in order to do that we need at least "enough" extension support in both libraries to make it tractable to use either one.</div>
<div><br></div><div><br></div><div>This isn't an argument for "all", merely for "enough". For example libc++ already has hash_map and hash_set, and that is probably the single most important container to support. We've now gotten a trial run conversion of a non-trivial chunk of our codebase to libc++, and the only other container that was missing was 'slist'. The only other missing extensions were a handful of very rarely used algorithms. Algorithms are much easier to work around than types, as two pieces of code can use different but compatible implementations without conflicting. I see no reason for libc++ to bother with these extensions.</div>
<div><br></div><div>The types are trickier. Had there been 10 extension types we needed, making 'slist' a slippery slope of extensions we might never get off of, I would be more sympathetic to drawing the line sooner and more forcefully. I think the best argument for adding a compatible 'slist' implementation is that it seems to be the last we'll need.</div>
</div>