On Tuesday, October 3, 2017 at 9:24:43 PM UTC-5, Niall Douglas wrote:Please find attached the finished D0762R0 paper.Feedback is very much welcomed on this paper.I'll turn my attention to the operator try proposing paper tomorrow night and try and get it done by end of week. Right now it's 3.23 am, I am going to bed!NiallI don't understand what this paper is actually proposing. Are you suggesting changes to the expected proposal? If so, what?
I don't understand what this paper is actually proposing. Are you suggesting changes to the expected proposal? If so, what?No, he wants `result` either in addition to or instead of `expected`. Essentially, he considers it fine to have both and fine to have `result`, but not fine to have just `expected`.
I don't think you have interpreted well the Boost review. The next
review will say.
2. All this is just a naming difference. Both provide narrow and wide
access contracts. We can spend as much time as we want bike-shedding.
4. I requested you to give examples on why expected couldn't have
[[nodiscard]] attribute.
IMHO, this could be a major point to justify a new class.
5. I'm all for been explicit and it is useful to have types that are not
default constructible. LEWG requested to maintain default construction
if T is default constructible.
IMHO, this is not a major point to justify a new class.
6. As other said, what prevents expected to propagate standard layout?
This could be a major point to justify a new class, if we don't know how
to do it for expected.
8. As I said to you , this is not true. Please point from where you have
this and we will fix it.
2.2 What prevent implementation of expected to use a struct based when
the types T, E are trivial. Could this be seen as a QoI?
2.3 I recognize that I have not addressed this point, but what prevent
expected to preserve it?
2.4 How checked<success<T>, failure<E>> would behave?
3 Conclusion
You lost me here. Are you saying that value should be narrow now?
> It's now a list of recommendations for changes to the expected proposal.
Does it have the full synopsis/interface and description of semantics
thereof, or are we just supposed to parse
it together from a list of recommendations?
>> > It's now a list of recommendations for changes to the expected proposal.
There might be a better chance of changing things if it's easier to
compare the full class synopses.
I realize you've already spent excessive amounts of energy on this
proposal, but I have no qualms about
asking for more, if/when it's important.
(ii) Require struct-based storage, prohibit union-based storage. Even simpler.
On 5 October 2017 at 00:40, Niall Douglas <nialldo...@gmail.com> wrote:
>>
>> > It's now a list of recommendations for changes to the expected proposal.
>>
>>
>> Does it have the full synopsis/interface and description of semantics
>> thereof, or are we just supposed to parse
>> it together from a list of recommendations?
>
>
> I have rewritten this paper entirely three times now. What you see now is
> what you're getting, bar fixed errata.
>
> Make of it whatever you choose. I entirely expect it to be completely
> ignored. I submit this paper because I believe the Expected proposal is
> suboptimal and I will sleep better in the future once it's standardised
> knowing that I tried to change things. That's all.
There might be a better chance of changing things if it's easier to
compare the full class synopses.
I realize you've already spent excessive amounts of energy on this
proposal, but I have no qualms about
asking for more, if/when it's important.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbmVYhbK_dy-196kSVUkcbZaUt6GKjXg89SV-MX8K8JsQ%40mail.gmail.com.
(ii) Require struct-based storage, prohibit union-based storage. Even simpler.What exactly does that have to do with a proposal for a type in the standard? That seems like a QoI detail. If it isn't, then what behavior does it change?
There might be a better chance of changing things if it's easier to
compare the full class synopses.And/or a table. Before vs After.I think we also need a table for some of the design choices of expected/result/outcome/etc.Basically a "menu" of choices that we can build from.(As long as that doesn't turn into a design-by-committee mess. Not all the choices in the table would be independent from other choices.)But I know that's a lot of work.
2. All this is just a naming difference. Both provide narrow and wide
access contracts. We can spend as much time as we want bike-shedding.
Sure, technically this is "just a naming difference". But that's exactly at the heart of the problem. I do go into some detail on my argument in this in section 2.1 "All wide or all narrow observers". I think Optional is wrong, and so is Expected for copying it. Names and naming matter.
4. I requested you to give examples on why expected couldn't have
[[nodiscard]] attribute.
IMHO, this could be a major point to justify a new class.
And as I replied to you, without some ability to inspect types for whether they have that attribute or not, it's a tricky thing for Expected due to its unfocused design remit.
As section 2.4 "Self disabling implicit constructors" points out, Outcome has a more focused design remit. That makes possible for it, things not possible for Expected.
5. I'm all for been explicit and it is useful to have types that are not
default constructible. LEWG requested to maintain default construction
if T is default constructible.
IMHO, this is not a major point to justify a new class.
I'm not sure where you're getting this "justify a new class" from. You told me by private email that that was not possible,
so I have dropped that request entirely from this paper. As per your feedback.
This paper is now exclusively about summarising the design differences and making recommendations for changes to Expected.
6. As other said, what prevents expected to propagate standard layout?
This could be a major point to justify a new class, if we don't know how
to do it for expected.
This is discussed in section 2.3 "Standard layout propagation"
8. As I said to you , this is not true. Please point from where you have
this and we will fix it.
The paper says "Checked requires type E to be default constructible". Note the "Checked".
2.2 What prevent implementation of expected to use a struct based when
the types T, E are trivial. Could this be seen as a QoI?
Discussed literally in the paper, with options discussed and a recommendation made.
2.3 I recognize that I have not addressed this point, but what prevent
expected to preserve it?
Discussed literally in the paper, with options discussed and a recommendation made.
3 Conclusion
You lost me here. Are you saying that value should be narrow now?
Yes. Remove all throwing behaviours and bad_expected_access entirely. Makes Expected simpler. If users want it to throw exceptions, they can very easily inherit Expected and tack that on.
I also recommend struct-based storage, not union-based storage. And that to be written into the spec. Again, Expected becomes simpler, and much easier for the compiler to compile the many hundreds of operations using Expected per compiland.
And finally I recommend that standard layout-ness be propagated. Those are the three recommendations I am making. I fully expect WG21 to ignore me, but I will live better in the future knowing that I tried to change things before it was too late.
typedef struct WhoCares
{
ActualType t;
ErrorCode e;
TypeEquivalentToBool b;
} RealName;
We can change this from expected. I believe the committee needs a paper with good a motivation, not just that optional was wrong and we should avoir this error again. We need something more factual.
What was not possible?I'm not sure where you're getting this "justify a new class" from. You told me by private email that that was not possible,
In this case this was not clear to me. I suggest to remove anything that distracts the reader, as the Boost.Revirew Outcome, result, checked, unchecked ....so I have dropped that request entirely from this paper. As per your feedback.
This paper is now exclusively about summarising the design differences and making recommendations for changes to Expected.
No need to compare the similarities and disimilarities woth something else. Just state clearly what you are against, explain why and propose something better.
A lot of people will not know what is your intent while reading the paper.
Ok, so you are proposing that optional<T> and expected<T,E> propagate standard layout. I guess variant will be in the same packet.
6. As other said, what prevents expected to propagate standard layout?
This could be a major point to justify a new class, if we don't know how
to do it for expected.
This is discussed in section 2.3 "Standard layout propagation"
Oh, I see it now. So you want, expected to require that T is default constructible?
Could you tell us why this is better?
Ok, so with the current wording an implementation could use a struct based layout. But this is not enough to you. You want to force a specific layout and not a QoI.
2.2 What prevent implementation of expected to use a struct based when
the types T, E are trivial. Could this be seen as a QoI?
Discussed literally in the paper, with options discussed and a recommendation made.
I'm not for adding this constraint to expected, other could agree with you. The standard doesn't dictate a layout of the implementation data members. It is only as if.
This could be a major reason to have a different class. The question1st is if the committee wants this feature for expected.
Please be more explicit on your paper. Add a specific section for removing bad_expected_access, ....Yes. Remove all throwing behaviours and bad_expected_access entirely. Makes Expected simpler. If users want it to throw exceptions, they can very easily inherit Expected and tack that on.
Why are you against having such functionality in expected, aside the name?
I will not be against removing value() that throw bad_expected_access if we have already something else that provide the same kind of behavior. I want a simple way to throw if there is no value. There are a lot of alternatives. My draft paper on ValueOrError types explores some of them. One thing at a time.
I believe that the committee is ready to discuss this 3 points (or even more if you had). Your paper should concentrate on these 3 points and remove anything else. Even if the paper is short it is distracting.
If you are not proposing a change, there is no need to signal a difference with respect your Outcome library.
This was my position i give to you for the first draft. Better to concentrate on the major differences that justify a change (or a new class) and let the minor things for another round.
As noted, the standard already has a convention on observers: narrow observers use operators, while wide observers use words. Therefore, if a type is going to provide only narrow observers, it should not use words whenever possible. That is, if `expected` is not going to provide wide observers, it should not have `.value` at all.
To do so creates confusion with `std::optional::value`'s contract.
Furthermore, having `value(expected)` have different behavior from `expected::value` is very confusing. Such an ADL function feels very much like a member operation. So if there is an `expected::value`, users will expect `value(expected)` to do the same thing.
If `value` is going to behave identically to `operator*/->`, then it shouldn't exist.
This is simply out-of-bounds for the specification. Even as an implementation notation, it's just outside the scope of what the standard committee does.
If you believe that implementations will be better off using struct-based storage, then you should go to the implementers and convince them to incorporate your ideas.
Also, it's not clear how "all struct" storage could even work. `T` is not required to be default constructible, nor should it. So how could you actually have a `T` in the `expected` in the event of an error? You'd have to wrap it in some type that is default constructible, which uses dynamic storage duration for the actual `T` and forwards the copy/move operations to its contained `T` when it is engaged appropriate. That requires writing all of that code you don't want to write.
It's important to understand that, despite the title of this section, you're talking about two very different things. The first as indicated by the title is having `expected<T, E>` be standard layout if T and E are standard layout. This would guarantee layout compatibility for things like the common-initial-sequence rules for unions and the like.
The second thing is explicitly defining what that layout shall be. You have to understand that this is a very different step from the above. The standards committee balked at giving a type as simple as `string_view` a well-defined layout (`const char*, std::size_t`). If they're unwilling to do it for a trivial type like that, they're certainly not going to for this.
Furthermore, your goal seems wrongheaded. You cite interoperability as a reason to do this, but the only way that can happen is if there are a bunch of C APIs that start taking/returning structs like this:
typedef struct WhoCares
{
ActualType t;
ErrorCode e;
TypeEquivalentToBool b;
} RealName;
I am not an expert on C APIs by any stretch, but I have never seen a C API that returned a struct anything like that. Your example is artificial because you control both the source and the destination APIs, so you could just as easily have created a C-style API that marshalls the `expected` properly.
I find it odd that you argue that narrow contracts are OK because we have static analysis tools, yet you ignore the fact that those same tools (or tools based on their ideas) can also be used to generate C/C++ marshalling code very easily. If my build process already includes static analysis, why not also include static code generation?
But I digress. Most instances of C/C++ interop, in my experience, are for C APIs that were primarily intended to be consumed by other C code. Most C APIs that return both an error code and an optional value use an output parameter, and the error code is the return value. The boolean is simply one of the states of the error code. Indeed, even for C APIs that return structs of value/error code, they don't include a boolean. The error code is always a valid value; you have to test the code to see if it indicates an actual error state.
So how exactly will making `expected` standard layout improve compatibility with C? Do you really expect to see a rash of C libraries adopting structs that are compatible with it?
This is in fact why I'm not annoyed by `string_view` not having a specific layout. Because C APIs don't use that layout anyway, nor will they do so just because we standardized one.
Lastly, the thing that makes it most difficult to use code written in C++ outside of C++ is the lack of a standard ABI. Making `expected` layout compatible changes none of the fundamental ABI issues that make interoperability difficult.
We can change this from expected. I believe the committee needs a paper with good a motivation, not just that optional was wrong and we should avoir this error again. We need something more factual.
I gave my rationale in the paper. It's about not being anti-social to end users: not adding to their cognitive load, not mish-mashing contracts into the same object, not burdening end users with having to think about exception safety.
I appreciate that all of these arguments make no sense to WG21 members. But you've got to remember you're all in the top 1% of C++ developers. You get this stuff. The average programmer does not, and curses all of you at WG21 for not thinking of what it's like at the coal face.
You then get significant C++ users banning all use of the STL in their major code bases precisely because of the anti-social-ness problem.
What was not possible?I'm not sure where you're getting this "justify a new class" from. You told me by private email that that was not possible,
More than one Expected-like object in the standard.
In this case this was not clear to me. I suggest to remove anything that distracts the reader, as the Boost.Revirew Outcome, result, checked, unchecked ....so I have dropped that request entirely from this paper. As per your feedback.
This paper is now exclusively about summarising the design differences and making recommendations for changes to Expected.
No need to compare the similarities and disimilarities woth something else. Just state clearly what you are against, explain why and propose something better.
A lot of people will not know what is your intent while reading the paper.
Do bear in mind Vicente that you've seen both previous editions, and that biased you. This paper shouldn't cause the same confusion, assuming they read the first page where it explicitly states what the paper is about (FYI draft 3 which you haven't seen strengthens the "what this paper is" in the intro).
Regarding comparing Outcome and Expected, I appreciate that you personally find that superfluous. But your colleagues do not. I've had more than half a dozen direct requests to publish an exact list of similarities and dissimilarities between post-Boost-review Outcome and present Expected. Indeed even on this thread, there have been calls for more detail on the design differences, not less.
Ok, so you are proposing that optional<T> and expected<T,E> propagate standard layout. I guess variant will be in the same packet.
6. As other said, what prevents expected to propagate standard layout?
This could be a major point to justify a new class, if we don't know how
to do it for expected.
This is discussed in section 2.3 "Standard layout propagation"
Ship has probably sailed on that too, but I'd like to hope that std2::variant<> will get that right one day so C can speak Variant.Oh, I see it now. So you want, expected to require that T is default constructible?
Could you tell us why this is better?
If you look more closely you'll see the flags permit neither T nor E to exist in the memory set aside for them.
Ok, so with the current wording an implementation could use a struct based layout. But this is not enough to you. You want to force a specific layout and not a QoI.
2.2 What prevent implementation of expected to use a struct based when
the types T, E are trivial. Could this be seen as a QoI?
Discussed literally in the paper, with options discussed and a recommendation made.
I'm not for adding this constraint to expected, other could agree with you. The standard doesn't dictate a layout of the implementation data members. It is only as if.
This could be a major reason to have a different class. The question1st is if the committee wants this feature for expected.
I personally think WG21's historical attitude to good relations with other programming languages has been abysmal. No other programming language out there works well with C++, which is quite frankly shocking, and entirely the fault of WG21.
And moreover it's highly damaging to the long term sustainability of the C++ ecosystem. The most galling thing of all is that even little minor improvements in specification detail would deliver outsize improvements. There really ought to be a WG21 study group dedicated to deeply integrating C++ and Python together. It would do wonders for our long term job prospects, and force the rest of WG21 to think about other people.
Please be more explicit on your paper. Add a specific section for removing bad_expected_access, ....Yes. Remove all throwing behaviours and bad_expected_access entirely. Makes Expected simpler. If users want it to throw exceptions, they can very easily inherit Expected and tack that on.
Why are you against having such functionality in expected, aside the name?
I explained in the paper multiple reasons. I repeated them above. Most importantly of all, UB detection tooling is so much better today than it used to be. Just because we used to have runtime checking observers does not mean they are wise today when they eliminate the usefulness of static and runtime correctness analysis. That is a huge cost and loss, and one totally unnecessary. If the programmer really wants potential exception throwing, it is trivial for them to add it in themselves. So don't build it into the standard! It's unnecessary!
I will not be against removing value() that throw bad_expected_access if we have already something else that provide the same kind of behavior. I want a simple way to throw if there is no value. There are a lot of alternatives. My draft paper on ValueOrError types explores some of them. One thing at a time.
As I suggested in my paper, an external mechanism like a free function observer interface which throws exceptions is fine by me. Your draft paper also is fine with me in principle. I'm arguing against the builtin assumption of it being wise that new objects added to C++ should ever throw an exception for a logic error. I think technological improvement has made that design choice unwise and suboptimal.
I believe that the committee is ready to discuss this 3 points (or even more if you had). Your paper should concentrate on these 3 points and remove anything else. Even if the paper is short it is distracting.
If you are not proposing a change, there is no need to signal a difference with respect your Outcome library.
This was my position i give to you for the first draft. Better to concentrate on the major differences that justify a change (or a new class) and let the minor things for another round.
I've reduced considerably the "ask" of the paper, partially in thanks to your feedback.
But other feedback wanted more detail on the design differences and why. You might remember the very first paper I wrote was just a long list of design differences and why. That's gone now, this third rewrite I think makes everyone giving feedback equally unhappy, which sounds about right to me.
As noted, the standard already has a convention on observers: narrow observers use operators, while wide observers use words. Therefore, if a type is going to provide only narrow observers, it should not use words whenever possible. That is, if `expected` is not going to provide wide observers, it should not have `.value` at all.That's fine, except there are not enough punctuation operators available. Expected makes .error() narrow for example. Me personally I'd have everything all narrow or everything all wide unless the name prefix says otherwise.To do so creates confusion with `std::optional::value`'s contract.The simple solution there is for Expected to drop operator* and operator-> and exclusively use narrow error and value.
Just because Optional got it wrong doesn't mean all new additions have to.
Furthermore, having `value(expected)` have different behavior from `expected::value` is very confusing. Such an ADL function feels very much like a member operation. So if there is an `expected::value`, users will expect `value(expected)` to do the same thing.It was just a suggestion. Vicente's got a paper which implements a more generic and nicer solution which in my opinion (not his) even more strongly suggests that the vocab types themselves ought to be all narrow for simplicity.
If `value` is going to behave identically to `operator*/->`, then it shouldn't exist.Agreed. Drop operator* and operator->. Those are for dereferencing. Neither Optional nor Expected is a pointer nor an iterator.
This is simply out-of-bounds for the specification. Even as an implementation notation, it's just outside the scope of what the standard committee does.The committee chooses its scope.
It can change its mind.
If you believe that implementations will be better off using struct-based storage, then you should go to the implementers and convince them to incorporate your ideas.
Also, it's not clear how "all struct" storage could even work. `T` is not required to be default constructible, nor should it. So how could you actually have a `T` in the `expected` in the event of an error? You'd have to wrap it in some type that is default constructible, which uses dynamic storage duration for the actual `T` and forwards the copy/move operations to its contained `T` when it is engaged appropriate. That requires writing all of that code you don't want to write.You're overthinking it. If you never access it, uninitialised storage for a T is legal.
struct Data
{
alignas(T) unsigned char[sizeof(T)] bits;
E error;
};
It's important to understand that, despite the title of this section, you're talking about two very different things. The first as indicated by the title is having `expected<T, E>` be standard layout if T and E are standard layout. This would guarantee layout compatibility for things like the common-initial-sequence rules for unions and the like.
The second thing is explicitly defining what that layout shall be. You have to understand that this is a very different step from the above. The standards committee balked at giving a type as simple as `string_view` a well-defined layout (`const char*, std::size_t`). If they're unwilling to do it for a trivial type like that, they're certainly not going to for this.I am very aware that my pleas will be ignored. I am aware of what happened with string_view, which was the wrong decision. Had it been guaranteed that layout (I'd actually have chosen { const char *, const char * }) with standard layoutness, all C speaking code could now speak string_view which would have been such a boon for interoperation, particularly as C strings are so inefficient and unsafe.If I had had the power, indeed I've have taken string_view to WG14 (C programming language) and started the process of standardising its C form over there. Big gain for them too.
Furthermore, your goal seems wrongheaded. You cite interoperability as a reason to do this, but the only way that can happen is if there are a bunch of C APIs that start taking/returning structs like this:
typedef struct WhoCares
{
ActualType t;
ErrorCode e;
TypeEquivalentToBool b;
} RealName;
I am not an expert on C APIs by any stretch, but I have never seen a C API that returned a struct anything like that. Your example is artificial because you control both the source and the destination APIs, so you could just as easily have created a C-style API that marshalls the `expected` properly.Well of course, C++ is a superset of C. You have to restrict your use of C++ to what C can understand.BTW here is the C API for Outcome: https://github.com/ned14/outcome/blob/master/include/outcome/result.h. We even use a fancy new C11 generic in there :)
I find it odd that you argue that narrow contracts are OK because we have static analysis tools, yet you ignore the fact that those same tools (or tools based on their ideas) can also be used to generate C/C++ marshalling code very easily. If my build process already includes static analysis, why not also include static code generation?
But I digress. Most instances of C/C++ interop, in my experience, are for C APIs that were primarily intended to be consumed by other C code. Most C APIs that return both an error code and an optional value use an output parameter, and the error code is the return value. The boolean is simply one of the states of the error code. Indeed, even for C APIs that return structs of value/error code, they don't include a boolean. The error code is always a valid value; you have to test the code to see if it indicates an actual error state.
So how exactly will making `expected` standard layout improve compatibility with C? Do you really expect to see a rash of C libraries adopting structs that are compatible with it?If WG21 made life just a little bit easier on C++ programmers needing to provide C compatibility so Python et al can reuse their code, I don't doubt you'd see a large uptick in usage.
Hell Rust has better support for foreign language interop than C++ does. And it's new.
This is in fact why I'm not annoyed by `string_view` not having a specific layout. Because C APIs don't use that layout anyway, nor will they do so just because we standardized one.I view it as an awful missed opportunity. C hasn't standardised an alternative to the null terminated char array due to lack of a standardised approach to adopt.
C++ setting a direction would give C the excuse to choose one over the others. Very unfortunate.Lastly, the thing that makes it most difficult to use code written in C++ outside of C++ is the lack of a standard ABI. Making `expected` layout compatible changes none of the fundamental ABI issues that make interoperability difficult.On that we certainly agree. I did a ton of R&D on solving this permanently for C++ some years ago. US$1.5m would solve it we ballparked. Still, little things which cost nobody here or at the STL vendors much
can deliver outsize benefits to the C++ ecosystem.
And what if I don't agree that having some interfaces that throw and some
that crash constitutes a burden? It's easy to take the opposition viewpoint
and call it "anti-social". It's a lot harder to actually demonstrate that
it really is a problem in practice.
C++ is not a safe language, nor is it *going to be*.
I appreciate that all of these arguments make no sense to WG21 members. But
> you've got to remember you're all in the top 1% of C++ developers. You get
> this stuff. The average programmer does not, and curses all of you at WG21
> for not thinking of what it's like at the coal face.
>
So, you're effectively saying that if we don't agree with how you see
things, then we're just ivory tower intellectuals who don't care about how
the hoi-polloi suffer? That it is impossible for us to understand the needs
of "the average programmer" yet still disagree with you?
Has it occurred to you that we don't find your argument convincing
because... your argument is not convincing?
You then get significant C++ users banning all use of the STL in their
> major code bases precisely because of the anti-social-ness problem.
>
... they do? Whom?
As far as I am aware, most places that ban the standard library do so
because they're doing low-level stuff and can't afford to suffer the
performance irregularities of `vector`, `list`, and the like, or who have
very specific performance needs that these types cannot satisfy. It's not
that they don't want to use them; it's that they *can't*, because those
types don't do what they need.
Can you point to developers who have restricted themselves entirely from
using the standard library because of this supposed "anti-social-ness
problem"?
>
>>
>>>
>>> 2.2 What prevent implementation of expected to use a struct based when
>>> the types T, E are trivial. Could this be seen as a QoI?
>>>
>>
>> Discussed literally in the paper, with options discussed and a
>> recommendation made.
>>
>> Ok, so with the current wording an implementation could use a struct
>> based layout. But this is not enough to you. You want to force a specific
>> layout and not a QoI.
>> I'm not for adding this constraint to expected, other could agree with
>> you. The standard doesn't dictate a layout of the implementation data
>> members. It is only as if.
>> This could be a major reason to have a different class. The question1st
>> is if the committee wants this feature for expected.
>>
>
> I personally think WG21's historical attitude to good relations with other
> programming languages has been abysmal. No other programming language out
> there works well with C++, which is quite frankly shocking, and entirely
> the fault of WG21.
>
How exactly is not having a standard ABI WG21's fault? After all, it's not
like WG14 defined an ABI either. Stop castigating WG21 for things that
aren't actually their fault.
And moreover it's highly damaging to the long term sustainability of the
> C++ ecosystem. The most galling thing of all is that even little minor
> improvements in specification detail would deliver outsize improvements.
> There really ought to be a WG21 study group dedicated to deeply integrating
> C++ and Python together.
>
How do you write against something that isn't a standard? Python doesn't
have a standard, so how can you have a standard interface to it?
It would do wonders for our long term job prospects, and force the rest of
> WG21 to think about other people.
>
Yeah, everyone believes that if the committee solved *their* problems, then
everyone in the C++ world would be better off. What makes this such
declaration any different from anyone else's similar declarations?