[std-interval] Suggestions for the 2006-09 draft

Gabriel Dos Reis gdr at integrable-solutions.net
Mon Sep 25 17:45:33 PDT 2006


Guillaume Melquiond <guillaume.melquiond at ens-lyon.fr> writes:

[...]

| William Walster's sentence "Surely, a proposed language standard should
| not be written in such a way that it can *only* be implemented in a
| class library." was quite clear to me at that time. Especially as having
| __interval__ T inside the interval class would not be helpful in
| performing "symbolic expression manipulation and derivative/slope
| derivation, and width/performance optimizations".

It certainly is a matter of fact that GCC performs relatively
high-level optmizations on __complex__ T use to implement std::complex<T>.  

If all access to the data are internally in terms of inline functions
(which I highly suspect will be the case), I'm not sure how having
__interval__ T inside the std::interval will not be helpful in performing
the mentioned transformations.

We can pretty much take it for a fact that, an interval proposal for
C++ that insists on built-in type "interval" has zero chance of
getting accepted.  The probability of a library-based solution,
comparatively, is much higher.  Also, because of language details, it
must be specified whether std::interval is a class or not.
>From there, there is no obligation to write down the actual
implementation part of that class.   It should be left
implementation-defined.  To accomodate the kind of transformations
William Walster suggested.

[...]

| > This is possible because the actual internal definition is left
| > implementation-defined.  I certainly do hope that the final
| > specification of the class template interval should not require the
| > private members as shown on page 13, but instead leave it
| > implemented-defined.   The whole class should be semantically complete
| > without referring to internal<>::data.
| 
| This idea was inspired from Howard Hinnant's N1589. Now I see that DR387
| currently suggests to have this kind of sentence instead: "If z is an
| lvalue expression of type cv std::interval<T> then the expression
| reinterpret_cast<cv T(&)[2]>(z) is well-formed". As the point of writing
| the "data" member was precisely to express this reinterpretability, this
| kind of sentence too is fine with me.

That is what I suggested (when I originally raised the issue) in the C++
standards committee paper "Enhancing numerical support", section 2.2.1

   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1388.pdf

The suggestions were approved the LWG (I distinctly remember the
session).  And, while I was not watching later meetings, a distraction
happened and the issue got set back from "Ready" state to "Open"
state. With no much progress over the original suggestions :-(

That paper also formally raised the std::complex<> as key in
associative container issue.  It was at that meeting that Andy Koenig
suggested the "canonical ordering" path be explored.

[...]

| Yes, I may have been underestimating this issue as there is no DR for
| this mistake for std::complex (is there?).

Many things are discussed through mails or face-to-face standard
meetings :-)

| Moreover, I am not really
| confortable with C++ localization mechanism. Do you have any idea of
| what is needed for a localized version of intervals? In particular,
| should we add members to the numeric category or should we specify a new
| category for intervals or is there another way? What would have been
| done for std::complex if something had been done?

Basically, the C++ standards specify that a std::complex<T> can be
read in as u, (u), or (u,v).  In countries (say France) where comma is
used for the "decimal point", (3,4) is not the same as 3+4i.  That is
a mistake.

I would suggest that num_get<> and num_put<> facets have overloaded
virtual member functions get() and put() to parse and un-parse
intervals.  That looks hand-handed to me but it is a better
alternative to the complex<T> mistake.

[...]

| > The issue of std::set<T>, where T is a floating point value is one
| > that keeps poping up.  In particular, that of
| > std::set<std::complex<T>> is very annyoing.  To solve this issue, it has 
| > been suggested several times (the first time I hear of it was from
| > Andy Koenig at the Santa Cruz meeting, October 2002) to introduce a
| > "canonical ordering" defined in terms of the value representation so
| > that even if it does not make sense to use operator< on complex<T>, it
| > should make sense to say std::set<complex<T>> as people expect.
| 
| Could you detail a bit more what was suggested at this meeting? That the
| definition of std::less<T> be changed so that it becomes a canonical
| ordering irrespective of the definition of operator<(T,T)? That a new
| class be specified to express a total ordering? Whatever consensus was
| reached at that time, we can adjust the proposal to it. The more details
| you can provide, the stronger the rationale will be. Thanks.

Andy Koenig's suggestion wasn't to redefine std::less.
In fact he expressed his concerns about the fact that std::less was no
longer synonymous for operator< -- std::less<T*> explicitly violates
that equivalence.

Rather, he suggested that a new ordering class is defined -- that will
be automatically supplied by the compiler+library -- to reflect the
implementations' view of ordering.  In particular that would take care
of the NaNs issue.

In recent discussions, that kind of property surfaces (along with
other properties) for what is called "regular types" -- they are types
that behave just like you would expect from int, double, etc.

[...]

| Just to be sure I understand correctly what you are saying. What you
| call "external semantics specification" is the ability to reinterpret an
| array of n std::interval<T> objects into an array of 2*n Ts, similarly
| to what is written in the defect report for std::complex, right? Or is
| there more to it, or less?

What I meant was that the semantics of the std::interval class should
be described independently of its actual private data members or such.
(I suspect the term "algebraic specification" is often used).  For
example (pardon the syntax),

   interval(a, b).lower() == a
   interval(a, b).high() == b

HTH.

-- Gaby


More information about the Std-interval mailing list