Number Concept Family

166 views
Skip to first unread message

Christopher Di Bella

unread,
Mar 26, 2017, 7:42:25 AM3/26/17
to ISO C++ Standard - Future Proposals, Casey Carter, Eric Niebler
Hey everyone,

I've been working on a Number concept for a little while, and I think it's ready to float out here.
Just wondering what your thoughts are? Proposal draft attached in PDF form.

Cheers,

Chris
number.pdf

Tony V E

unread,
Mar 26, 2017, 10:01:27 AM3/26/17
to ISO C++ Standard - Future Proposals, Casey Carter, Eric Niebler
'Regular' is already a concept - a very important one, so I would expect RegularNumber to be a Number that was Regular. 

You might look to mathematics and call it a FieldNumber. 


Sent from my BlackBerry portable Babbage Device
From: Christopher Di Bella
Sent: Sunday, March 26, 2017 7:42 AM
To: ISO C++ Standard - Future Proposals
Cc: Casey Carter; Eric Niebler
Subject: [std-proposals] Number Concept Family

--
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-proposal...@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/50075dd2-ae2a-4022-8e94-196d44e34687%40isocpp.org.

Vicente J. Botet Escriba

unread,
Mar 26, 2017, 11:24:56 AM3/26/17
to std-pr...@isocpp.org, Casey Carter, Eric Niebler
Hi,

why do you associate pre-increments and post-increment to an ordered number?

Why char types are not considered as Numbers? isn't int8_t a Number?

I don't see the operator% on you clasification.

Where numeric types that double the range under addition and multiplication

T + T -> D(T) // D(T) means a type that double the range of T

T * T -> D(T)

will fall on this clasification?

Vicente

Christopher Di Bella

unread,
Mar 26, 2017, 4:05:43 PM3/26/17
to std-pr...@isocpp.org, Casey Carter, Eric Niebler


> 'Regular' is already a concept - a very important one, so I would expect RegularNumber to be a Number that was Regular. You might look to mathematics and call it a FieldNumber.

Excellent suggestion! I really like this :)
Number requires Regular: the idea for naming "RegularNumber" came from "RegularInvocable", which only has semantic differences to Invocable.

> why do you associate pre-increments and post-increment to an ordered number?

Poor naming decisions. The other name that I came up with for OrderedNumber was StrictNumber, but I preferred OrderedNumber, since I couldn't think of any non-ordered numbers that can be incremented, and communicates the strict ordering imposed. Something like s/Number/WeakNumber/ s/OrderedNumber/Number/ is desirable, but "WeakNumber" needs some justification I can't provide.


> Why char types are not considered as Numbers? isn't int8_t a Number?

int8_t is a signed integral; it should be a signed char^, which is a distinct type from char. char is not a Number, it is a character type that is also an arithmetic type, but signed char is a Number. Number is not intended to be a super-set of arithmetic types.

^It's strictly implementation-defined, but I don't think it can be a char either way?


> I don't see the operator% on you clasification

operator% is a tricky one: floating-point numbers don't support operator%. Does it make sense to use operator% on a some type that isn't an integer? If so, it would be a good addition for RegularNumber/FieldNumber, but I think there should be a general group of numbers that we can use operator% on.

Where numeric types that double the range under addition and multiplication
> T + T -> D(T)  // D(T) means a type that double the range of T
> T * T -> D(T)
> will fall on this clasification?

I am not sure I understand this one. Can you provide a concrete example, please?

Cheers,

Chris

--
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-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

Nicol Bolas

unread,
Mar 26, 2017, 5:04:19 PM3/26/17
to ISO C++ Standard - Future Proposals, ca...@carter.net, eric.n...@gmail.com
On Sunday, March 26, 2017 at 4:05:43 PM UTC-4, Christopher Di Bella wrote:
> Why char types are not considered as Numbers? isn't int8_t a Number?

int8_t is a signed integral; it should be a signed char^, which is a distinct type from char. char is not a Number, it is a character type that is also an arithmetic type, but signed char is a Number. Number is not intended to be a super-set of arithmetic types.

^It's strictly implementation-defined, but I don't think it can be a char either way?

It could be `char` if the implementation makes `char` an 8-bit signed, two's complement integer. So you cannot assume that it isn't `char`.

Vicente J. Botet Escriba

unread,
Mar 26, 2017, 5:37:07 PM3/26/17
to std-pr...@isocpp.org, Casey Carter, Eric Niebler
Le 26/03/2017 à 22:05, Christopher Di Bella a écrit :



> why do you associate pre-increments and post-increment to an ordered number?

Poor naming decisions. The other name that I came up with for OrderedNumber was StrictNumber, but I preferred OrderedNumber, since I couldn't think of any non-ordered numbers that can be incremented, and communicates the strict ordering imposed. Something like s/Number/WeakNumber/ s/OrderedNumber/Number/ is desirable, but "WeakNumber" needs some justification I can't provide.

It is weird to have += on a type and don't have increment.

> Why char types are not considered as Numbers? isn't int8_t a Number?

int8_t is a signed integral; it should be a signed char^, which is a distinct type from char. char is not a Number, it is a character type that is also an arithmetic type, but signed char is a Number. Number is not intended to be a super-set of arithmetic types.

Sorry I meant uint8_t.

^It's strictly implementation-defined, but I don't think it can be a char either way?
So we couldn't have an unsigned Number of 8 bits, at least not a builtin one :(
After a deep reading you add

{-cn} -> N;

So you are considering only number with closed arithmetic.

cardinal  (as proposed  in n3352) is not closed for the - operation.

    -cardinal -> integral
    cardinal - cardinal -> integral
 
C++ Binary Fixed-Point Arithmetic http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html

an so it couldn't be a Number


> I don't see the operator% on you clasification

operator% is a tricky one: floating-point numbers don't support operator%. Does it make sense to use operator% on a some type that isn't an integer? If so, it would be a good addition for RegularNumber/FieldNumber, but I think there should be a general group of numbers that we can use operator% on.
I'm not an expert, but I believe that it has a sens only for integer numbers. I  was wondering just why this operation is not considered in your classification, while you consider bitwise operations.


Where numeric types that double the range under addition and multiplication
> T + T -> D(T)  // D(T) means a type that double the range of T
> T * T -> D(T)
> will fall on this clasification?

I am not sure I understand this one. Can you provide a concrete example, please?



I was thinking of safe numbers

    safe<short> * safe<short> -> safe<int>

or fixed point numbers (as proposed by L. Crowl in n3352).

or bounded::integer ( http://doublewise.net/c++/bounded/)

Which kind of Numbers would be those?

Best,
Vicente

T. C.

unread,
Mar 26, 2017, 7:39:01 PM3/26/17
to ISO C++ Standard - Future Proposals, ca...@carter.net, eric.n...@gmail.com
No. It's required to be a "signed integer type", which plain char isn't regardless of representation. See [basic.fundamental]/2, C11 6.2.5/4, 7.20.1.1/1.

Tony V E

unread,
Mar 26, 2017, 10:42:01 PM3/26/17
to Standard Proposals
On Sun, Mar 26, 2017 at 5:37 PM, Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
Le 26/03/2017 à 22:05, Christopher Di Bella a écrit :



> why do you associate pre-increments and post-increment to an ordered number?

Poor naming decisions. The other name that I came up with for OrderedNumber was StrictNumber, but I preferred OrderedNumber, since I couldn't think of any non-ordered numbers that can be incremented, and communicates the strict ordering imposed. Something like s/Number/WeakNumber/ s/OrderedNumber/Number/ is desirable, but "WeakNumber" needs some justification I can't provide.

It is weird to have += on a type and don't have increment.

It is weird.

And it depends how "mathy" we want to get.  When I see OrderedNumber, I think "ordinal".  ie 1st 2nd 3rd instead of 1 2 3.

An ordinal would/should have a ++ ("successor") and += would be like std::advance().  But it wouldn't be operator+=(Ordinal ord), it would be operator+=(int amount) - ie give me the 5th ordinal after this one.

ie if doubles were Ordinals ++ would/should give you the _next_ double.  Just like an iterator does.

I'm not saying we want Ordinals; I'm saying we need to think carefully.

--
Be seeing you,
Tony

John McFarlane

unread,
Mar 27, 2017, 12:10:29 PM3/27/17
to std-pr...@isocpp.org, Casey Carter, Eric Niebler
On Sun, Mar 26, 2017 at 2:37 PM Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
Le 26/03/2017 à 22:05, Christopher Di Bella a écrit :
...
So we couldn't have an unsigned Number of 8 bits, at least not a builtin one :(
After a deep reading you add

{-cn} -> N;

So you are considering only number with closed arithmetic.

cardinal  (as proposed  in n3352) is not closed for the - operation.

    -cardinal -> integral
    cardinal - cardinal -> integral
 
C++ Binary Fixed-Point Arithmetic http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html

an so it couldn't be a Number

This is certainly an interesting paper, but Number etc. seem to be on the exclusive side. I've no idea whether this is a good idea or not.

It's not just many of the types being considered for a Numerics TS which would fail Number. Consider dimensional analysis types such as those in Boost.Units. Returning novel types is very useful but is commonly overlooked.

Also, Number seems to exclude integers shorter than `int` because it expects results of binary arithmetic to be `common_type_t` whereas the result of some integer arithmetic operations is promoted to `int`.

Perhaps what are being described here are types which can replace fundamental scalar types under certain circumstances. For instance, compositional types such as `std::chrono::duration` might be instantiated on a type which supports some arithmetic operators but not others. The resultant type will be similarly limited but still correct and "numbery". It might be useful to say that `duration<Rep>` is a Number iff `Rep` is also a Number.

Could there be a concept for types which do not wrap around on overflow? When you add 1 to a signed type, it should always be greater. That's a very valuable property which does not extend to unsigned types.

John

Robert Ramey

unread,
Mar 27, 2017, 12:47:54 PM3/27/17
to std-pr...@isocpp.org
On 3/27/17 9:10 AM, John McFarlane wrote:

> This is certainly an interesting paper, but Number etc. seem to be on
> the exclusive side. I've no idea whether this is a good idea or not.

I'm in agreement with this sentiment. I'm not really understanding what
this would be used for and why it would be helpful. We use the word
"Number" (and by implication the concept of "Number") in a variety of
ways which sometimes from conflict. If you pin it down to something
pretty specific like the mathematical notion of "integers" or "positive
integers", you'd have something that is precise - but not particularly
useful in context where we work.

As an exercise, one might try to apply the "Number Concept" to the
variety of "numbers" we've already been working with in our real code.
I think the utility would be limited.

I would characterise this idea of one of "premature conceptualization"

Robert Ramey

Vicente J. Botet Escriba

unread,
Mar 27, 2017, 2:36:35 PM3/27/17
to std-pr...@isocpp.org
Le 27/03/2017 à 04:41, Tony V E a écrit :


On Sun, Mar 26, 2017 at 5:37 PM, Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
Le 26/03/2017 à 22:05, Christopher Di Bella a écrit :



> why do you associate pre-increments and post-increment to an ordered number?

Poor naming decisions. The other name that I came up with for OrderedNumber was StrictNumber, but I preferred OrderedNumber, since I couldn't think of any non-ordered numbers that can be incremented, and communicates the strict ordering imposed. Something like s/Number/WeakNumber/ s/OrderedNumber/Number/ is desirable, but "WeakNumber" needs some justification I can't provide.

It is weird to have += on a type and don't have increment.

It is weird.

And it depends how "mathy" we want to get.  When I see OrderedNumber, I think "ordinal".  ie 1st 2nd 3rd instead of 1 2 3.

An ordinal would/should have a ++ ("successor") and += would be like std::advance().  But it wouldn't be operator+=(Ordinal ord), it would be operator+=(int amount) - ie give me the 5th ordinal after this one.
I agree completly. We can not add Monday and Saturday.

But we are not talking of Ordinals, but flat Numbers, scalars. I will expect ++n, n++, n+= cn, auto x = cn+cm. 


ie if doubles were Ordinals ++ would/should give you the _next_ double.  Just like an iterator does.
I don't think so. We have that ++ on doubles with the semantic of ++x   x += 1.

I cannot consider double as an ordinal, but I can request that ++x is valid with the x += 1 semantics.


BTW, for Regular Numbers I will request N{1} and require the identity axioms for +,N{0} and *,N{1}.

And what about the numeric_limits, do we require that a Number N has its numeric_limits<N>



I'm not saying we want Ordinals; I'm saying we need to think carefully.
I want Ordinals ;-) Not in this proposal, of course.
I want to be able to index an array with an Ordinal, well if not a c-array, at least for an ordinal_array<T, Ordinal>.
Not having this kind of type makes very unfriendly to use strongly types.

E.g. if we define a type

bounded<0,9> b;

Do we need to get the underlying representation to access and array

    arr[b.value()]

or we want to just

    arr[b]

Note that I'm not requiring an implicitt conversion from bounded to int. But this is out of the scope of this thread.

Vicente

Vicente J. Botet Escriba

unread,
Mar 27, 2017, 2:36:50 PM3/27/17
to std-pr...@isocpp.org, Casey Carter, Eric Niebler
Le 27/03/2017 à 18:10, John McFarlane a écrit :
On Sun, Mar 26, 2017 at 2:37 PM Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
Le 26/03/2017 à 22:05, Christopher Di Bella a écrit :
...
So we couldn't have an unsigned Number of 8 bits, at least not a builtin one :(
After a deep reading you add

{-cn} -> N;

So you are considering only number with closed arithmetic.

cardinal  (as proposed  in n3352) is not closed for the - operation.

    -cardinal -> integral
    cardinal - cardinal -> integral
 
C++ Binary Fixed-Point Arithmetic http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3352.html

an so it couldn't be a Number

This is certainly an interesting paper, but Number etc. seem to be on the exclusive side. I've no idea whether this is a good idea or not.

It's not just many of the types being considered for a Numerics TS which would fail Number. Consider dimensional analysis types such as those in Boost.Units. Returning novel types is very useful but is commonly overlooked.
I don't consider a quantity asa  raw Number. A quantity has very specific operators.


Also, Number seems to exclude integers shorter than `int` because it expects results of binary arithmetic to be `common_type_t` whereas the result of some integer arithmetic operations is promoted to `int`.
Right. builtin short is already in line with my example

    short + short => int


Perhaps what are being described here are types which can replace fundamental scalar types under certain circumstances. For instance, compositional types such as `std::chrono::duration` might be instantiated on a type which supports some arithmetic operators but not others. The resultant type will be similarly limited but still correct and "numbery". It might be useful to say that `duration<Rep>` is a Number iff `Rep` is also a Number.
No. duration<Rep, Period> would fall on the 1-dimensinal quantity. The operations are not the same as those of a Number. Note that some of the operations, e.g. *,/ and % can take a Regular Number on the rhs parameter. However, the Rep parameter must be a Regular Number.


Could there be a concept for types which do not wrap around on overflow? When you add 1 to a signed type, it should always be greater. That's a very valuable property which does not extend to unsigned types.
We can wrap an unsigned type and give it this semantic. There is a cost of course. See the proposed boost::numeric::safe integer.

Vicente

Christopher Di Bella

unread,
Mar 27, 2017, 4:25:20 PM3/27/17
to ISO C++ Standard - Future Proposals, ca...@carter.net, eric.n...@gmail.com
Lots of great feedback so far :)
I apologise if I miss your contributions: I've got a lot to work with. Please don't be shy to raise a point twice.

No. It's required to be a "signed integer type", which plain char isn't regardless of representation

Thanks for the clarification :)

> So we couldn't have an unsigned Number of 8 bits, at least not a builtin one :(  

Both signed char and unsigned char are permitted, which means that int8_t and uint8_t are allowed :)

> And it depends how "mathy" we want to get.  When I see OrderedNumber, I think "ordinal".  ie 1st 2nd 3rd instead of 1 2 3.
>
> An ordinal would/should have a ++ ("successor") and += would be like std::advance().  But it wouldn't be operator+=(Ordinal ord), it would be operator+=(int amount) - ie give me the 5th ordinal after this one.
>
> ie if doubles were Ordinals ++ would/should give you the _next_ double.  Just like an iterator does.
>
> I'm not saying we want Ordinals; I'm saying we need to think carefully.

I'm fielding a name new name for Number:

s/Number/BasicNumber/
s/OrderedNumber/Number/

Thoughts? Until I get some feedback on this, Number still refers to the base concept.
Ordinals haven't been considered at all.

It is weird to have += on a type and don't have increment.
It is weird.

I thought so too, but types such as complex don't support operator++, etc., which is why I moved it, along with StrictTotallyOrdered out of Number. I think the trick here is to work out what a "Number" really should be, and not to let types such as complex or N3352's cardinal dictate the requirements.

I'm not an expert, but I believe that it has a sens only for integer numbers. I  was wondering just why this operation is not considered in your classification, while you consider bitwise operations.

This is a good point: it's the only mathematical operator missing, but I can't think of a good way to include it. Definitely open to suggestions.

I was thinking of safe numbers 
>
>    safe<short> * safe<short> -> safe<int>
>
> or fixed point numbers (as proposed by L. Crowl in n3352).
>
> or bounded::integer ( http://doublewise.net/c++/bounded/)
>
> Which kind of Numbers would be those?

As an exercise, one might try to apply the "Number Concept" to the
> variety of "numbers" we've already been working with in our real code.
> I think the utility would be limited.  

I'm currently working with bounded::integer and the Boost-proposed safe<int>. I've also emailed Lawrence to find out if there's a prototype for N3352, so I can toy with that.
I'll look for some other numbers to toy with and report back. The critical key here is to produce real-world examples, not just contrived examples.

Could there be a concept for types which do not wrap around on overflow? When you add 1 to a signed type, it should always be greater. That's a very valuable property which does not extend to unsigned types.

Only if we can syntactically assert this, but this feels like a property of a concept, rather than a concept itself. I'd need to see more to be convinced either way, but I am definitely erring on the side of property.

> It's not just many of the types being considered for a Numerics TS which would fail Number. Consider dimensional analysis types such as those in Boost.Units. Returning novel types is very useful but is commonly overlooked.
Perhaps what are being described here are types which can replace fundamental scalar types under certain circumstances.


> This is certainly an interesting paper, but Number etc. seem to be on
> the exclusive side. I've no idea whether this is a good idea or not.

> I'm in agreement with this sentiment.  I'm not really understanding what
> this would be used for and why it would be helpful.  We use the word
> "Number" (and by implication the concept of "Number") in a variety of
> ways which sometimes from conflict.

I will confess that the only types that I've considered are fundamentals and types that mimic fundamentals. It never even occurred to me that there might be other ways to represent a number. The implicit motivation (based off my actions, not words) is for an algorithm or type to be allowed to accept any type that can be used like an integer or floating-point and use it as such. I'm not even sure I consciously was aware of this while writing. This will likely go back to the case study suggested above.

BTW, for Regular Numbers I will request N{1} and require the identity axioms for +,N{0} and *,N{1}.

N{1} would be the same as N{0}, since it's constructing N from an int-literal. How would this be semantically different to N{0}?
I do like where you're going with these though, so if there's an number-r2.pdf, they'll be in there as textual semantic requirements.

I want Ordinals... rest of email

Interesting ideas there :)


>> Also, Number seems to exclude integers shorter than `int` because it expects results of binary arithmetic to be `common_type_t` whereas the result of some integer arithmetic operations is promoted to `int`.
> Right. builtin short is already in line with my example
> short + short => int

Hmm... I wasn't aware of this, but Number<T, U> is definitely valid for all fundamentals T and U, at least on GCC. Won't know anything else until Clang or MSVC implement Concepts too. This failing would be a non-starter/staller.

No. duration<Rep, Period> would fall on the 1-dimensinal quantity. The operations are not the same as those of a Number. Note that some of the operations, e.g. *,/ and % can > take a Regular Number on the rhs parameter. However, the Rep parameter must be a Regular Number.  

I think that's what John means:
template <RegularNumber Rep, typename Period>
class duration;

That's definitely something I'd like to see it used for.

I would characterise this idea of one of "premature conceptualization"

Possibly!



Please let me know if I missed something that you'd like addressed!

Cheers,

Chris

--
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-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

Casey Carter

unread,
Mar 28, 2017, 12:55:43 AM3/28/17
to Christopher Di Bella, ISO C++ Standard - Future Proposals, Eric Niebler
This proposal is critically missing a list of use cases, which naturally gives rise to the confusion in the discussion thread. Everyone everywhere is going to point out every example they can recall of a number-like thing that doesn't fit the proposed concepts, and none of us can ascertain which of those examples is or is not in scope. Concept(s) which try to satisfy everyone's notion of what a number should be will likely be so watered down as to be useless for any actual use cases.

The other lack I see is that the presentation of the concepts is almost entirely syntactic. Lists of operations without meaning do not support equational reasoning, which is the entire point of having concepts. The major feature of e.g. CopyConstructible is not that the syntax "T a = b;" must be valid, it's that after that definition we are guaranteed that a is equal to b and b is unmodified. Without semantics, I don't know what these concepts *mean* so I cannot evaluate their utility.

Confusion about uses is to a large extent unavoidable with a name as general as Number. I urge you to maintain focus by enumerating a set of use cases, algorithms and/or classes that require Numbers, and using a characterization of their requirements to define your concepts. From that seed, you can develop the concepts organically by gradually growing the set of use cases the concepts can constrain and/or finding the boundaries that require you to add new concepts to cover additional use cases without over-diluting the existing concepts.

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.

Vicente J. Botet Escriba

unread,
Mar 28, 2017, 1:27:38 AM3/28/17
to std-pr...@isocpp.org, ca...@carter.net, eric.n...@gmail.com
Le 27/03/2017 à 22:25, Christopher Di Bella a écrit :
Lots of great feedback so far :)
I apologise if I miss your contributions: I've got a lot to work with. Please don't be shy to raise a point twice.

No. It's required to be a "signed integer type", which plain char isn't regardless of representation

Thanks for the clarification :)

> So we couldn't have an unsigned Number of 8 bits, at least not a builtin one :(  

Both signed char and unsigned char are permitted, which means that int8_t and uint8_t are allowed :)

My comment concerns this part of your proposal

template <class N>
concept bool Number() {
    return !Same<bool, N>() &&
        !Same<char, N>() &&
        !Same<wchar_t, N>() &&
        !Same<char16_t, N>() &&
        !Same<char32_t, N>() &&

> And it depends how "mathy" we want to get.  When I see OrderedNumber, I think "ordinal".  ie 1st 2nd 3rd instead of 1 2 3.
>
> An ordinal would/should have a ++ ("successor") and += would be like std::advance().  But it wouldn't be operator+=(Ordinal ord), it would be operator+=(int amount) - ie give me the 5th ordinal after this one.
>
> ie if doubles were Ordinals ++ would/should give you the _next_ double.  Just like an iterator does.
>
> I'm not saying we want Ordinals; I'm saying we need to think carefully.

I'm fielding a name new name for Number:

s/Number/BasicNumber/
s/OrderedNumber/Number/

Thoughts? Until I get some feedback on this, Number still refers to the base concept.

What about using Math. If we forget Natural number (no sign)

Number
    Integral
    Fractional
    Floating
    Complex
...

I believe that it will be useful to see where the existing builtin and standard numeric types fall on the classification.

C++ overload of operator/() let think that it is the same when we apply to Integral numbers and to Fractional/Floating numbers. However it is a different operation. For Integral types operator/ is inseparable from operator%, while for Fractionals/Floating % has no sens.
We shouldn't base the concepts in syntactical constraints. Even if all the number support the operator / it shouldn't be associated to Number, because the semantic is not the same. For integrals we should define which kind of truncation applies to them when we use i/j.

Due to overloading, some algorithms could work with integral division and fractional/floating division. I'm not sure that this would imply that the overloaded operator/ must be part of the operations of Number. The algorithms should then parametrized for Integral or fractional/floating.

If we allow unsigned numbers, the - operation lost its signification, and so it shouldn't be part of all the Numbers.
Here it is a possible classification

Number N(int), +_,_+_, _*_, ==, !=
    SignedNumber -_, _-_
        OrderedSignedNumber  <, <=, >, >=
            Integral, /, %
            Fractional /
            Floating N(float) /
        Complex /
    UnsignedNumber -_, _-_  (possible, but with a different semantic)
        OrderedUnsignedNumber   <, <=, >, >=


Ordinals haven't been considered at all.

It is weird to have += on a type and don't have increment.
It is weird.

I thought so too, but types such as complex don't support operator++, etc.,
I believe std::complex need some rework, making explicit imaginary numbers (There were a proposal in this sens, I don't remember if here or in Boost).
I don't see why we cannot do ++c on a complex. operator++ should be the same as c+= 1, and complex support this already.
I'm surely missing the meaning of ++n.

which is why I moved it, along with StrictTotallyOrdered out of Number. I think the trick here is to work out what a "Number" really should be, and not to let types such as complex or N3352's cardinal dictate the requirements.
Agreed.

Does the standard library and the C++ language use ++n as the successor of n (when n is a number) and limit this operation to ordinal StrictTotallyOrdered?  
Do we consider double~{NAN} as a StrictTotallyOrdered? Note that the meaning of ++d couldn't be the successor or otherwise float will not be satisfy StrictTotallyOrdered. If ++n must not be the same as n+=1 then the operation shouldn't belong to Number. However we need to define what it means and see if ++int and ++float satisfy  the this semantics.

I'm not an expert, but I believe that it has a sens only for integer numbers. I  was wondering just why this operation is not considered in your classification, while you consider bitwise operations.

This is a good point: it's the only mathematical operator missing, but I can't think of a good way to include it. Definitely open to suggestions.
This operation should be reserved to Integral types.


I was thinking of safe numbers 
>
>    safe<short> * safe<short> -> safe<int>
>
> or fixed point numbers (as proposed by L. Crowl in n3352).
>
> or bounded::integer ( http://doublewise.net/c++/bounded/)
>
> Which kind of Numbers would be those?

As an exercise, one might try to apply the "Number Concept" to the
> variety of "numbers" we've already been working with in our real code.
> I think the utility would be limited.  

I'm currently working with bounded::integer and the Boost-proposed safe<int>. I've also emailed Lawrence to find out if there's a prototype for N3352, so I can toy with that.
I'll look for some other numbers to toy with and report back. The critical key here is to produce real-world examples, not just contrived examples.
IIUC, you don't find contrived bounded::integer and safe<int>, fixed point numbers, or do you?


Could there be a concept for types which do not wrap around on overflow? When you add 1 to a signed type, it should always be greater. That's a very valuable property which does not extend to unsigned types.

Only if we can syntactically assert this, but this feels like a property of a concept, rather than a concept itself. I'd need to see more to be convinced either way, but I am definitely erring on the side of property.

Concepts have more than syntactical properties. In the same way you have added commutativity, you can add no wrapping.

> It's not just many of the types being considered for a Numerics TS which would fail Number. Consider dimensional analysis types such as those in Boost.Units. Returning novel types is very useful but is commonly overlooked.
Perhaps what are being described here are types which can replace fundamental scalar types under certain circumstances.


> This is certainly an interesting paper, but Number etc. seem to be on
> the exclusive side. I've no idea whether this is a good idea or not.

> I'm in agreement with this sentiment.  I'm not really understanding what
> this would be used for and why it would be helpful.  We use the word
> "Number" (and by implication the concept of "Number") in a variety of
> ways which sometimes from conflict.

I will confess that the only types that I've considered are fundamentals and types that mimic fundamentals. It never even occurred to me that there might be other ways to represent a number. The implicit motivation (based off my actions, not words) is for an algorithm or type to be allowed to accept any type that can be used like an integer or floating-point and use it as such. I'm not even sure I consciously was aware of this while writing. This will likely go back to the case study suggested above.

BTW, for Regular Numbers I will request N{1} and require the identity axioms for +,N{0} and *,N{1}.

N{1} would be the same as N{0}, since it's constructing N from an int-literal. How would this be semantically different to N{0}?
I do like where you're going with these though, so if there's an number-r2.pdf, they'll be in there as textual semantic requirements.
Yes, you are right. Any `signed` Number should be convertible from int, and so this will appear as a constraint
int i

N{i}




>> Also, Number seems to exclude integers shorter than `int` because it expects results of binary arithmetic to be `common_type_t` whereas the result of some integer arithmetic operations is promoted to `int`.
> Right. builtin short is already in line with my example
> short + short => int

Hmm... I wasn't aware of this, but Number<T, U> is definitely valid for all fundamentals T and U, at least on GCC. Won't know anything else until Clang or MSVC implement Concepts too. This failing would be a non-starter/staller.
No. The proposed Number<short,int> doesn't cover
    short + short => int

It includes mixed arithmetic
    short + int => int
    int + short => int

but no promotion.


No. duration<Rep, Period> would fall on the 1-dimensinal quantity. The operations are not the same as those of a Number. Note that some of the operations, e.g. *,/ and % can > take a Regular Number on the rhs parameter. However, the Rep parameter must be a Regular Number.  

I think that's what John means:
template <RegularNumber Rep, typename Period>
class duration;

That's definitely something I'd like to see it used for.
What I meant is that we can not use duration<R,P> as representation of another duration because it is not a RegularNumber :(
BTW, the standard std::duration forbids the use of duration<R,P> as a possible representation.

I would characterise this idea of one of "premature conceptualization"

Possibly!

I believe that what Robert means is that we should conceptualize the parameters of generic functions. We should start by the generic algorithms.

While the Range Ts has some numeric types, I don't think there is enough material there for this classification.

This should be part of the Numeric library.

std::duration<R,P> could be used to see what is required from R.

Note that duration<R,P> behaves quite differently depending on the trait treat_as_floating_point<R>. I see this as a union of concepts.

Vicente

Matthew Woehlke

unread,
Mar 28, 2017, 10:14:33 AM3/28/17
to std-pr...@isocpp.org
On 2017-03-26 16:05, Christopher Di Bella wrote:
> On 2017-03-26 11:24, Vicente J. Botet Escriba wrote:
>> I don't see the operator% on you clasification
>
> operator% is a tricky one: floating-point numbers don't support operator%.
> Does it make sense to use operator% on a some type that isn't an integer?
> If so, it would be a good addition for RegularNumber/FieldNumber, but I
> think there should be a general group of numbers that we can use operator%
> on.

FWIW, I'm not aware of the historical reasons why `operator%` is not
defined for floating point types, but it certainly isn't because you
can't do modulo arithmetic on them... for some reason, that operation
for floating points is spelled `fmod` instead of `operator%`.

--
Matthew

Robert Ramey

unread,
Mar 28, 2017, 11:57:57 AM3/28/17
to std-pr...@isocpp.org
On 3/27/17 9:55 PM, Casey Carter wrote:
> This proposal is critically missing a list of use cases, which naturally
> gives rise to the confusion in the discussion thread. Everyone
> everywhere is going to point out every example they can recall of a
> number-like thing that doesn't fit the proposed concepts, and none of us
> can ascertain which of those examples is or is not in scope. Concept(s)
> which try to satisfy everyone's notion of what a number should be will
> likely be so watered down as to be useless for any actual use cases.
>

+1

Robert Ramey

John McFarlane

unread,
Mar 28, 2017, 2:39:09 PM3/28/17
to std-pr...@isocpp.org, ca...@carter.net, eric.n...@gmail.com
On Mon, Mar 27, 2017 at 1:25 PM Christopher Di Bella <cjd...@gmail.com> wrote:
I'm currently working with bounded::integer and the Boost-proposed safe<int>. I've also emailed Lawrence to find out if there's a prototype for N3352, so I can toy with that.
I'll look for some other numbers to toy with and report back. The critical key here is to produce real-world examples, not just contrived examples.

Lawrence's proposal has been prototyped here: https://github.com/BoostGSoC15/fixed_point

Please also take a look at [https://github.com/johnmcfarlane/fixed_point] and in particular proposal, P0554. There is a possibility that elements of those numeric types will be included in the Numeric TS. Also, I list quite a few other libraries in P0554 which might be of interested.
Reply all
Reply to author
Forward
0 new messages