On Tue, Oct 3, 2023 at 2:21 AM Julien Jorge via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Regarding the description of nspan, you wrote:

 > We don't use span because present day code uses it differently. For
example you can not pass span into a function with the same type but
smaller length.

It seems to me that this restriction can be lifted by changing the
constraint of 24.7.2.2.2 §19.2 from

    extent == dynamic_extent
       || OtherExtent == dynamic_extent
       || extent == OtherExtent

to

    extent == dynamic_extent
       || OtherExtent == dynamic_extent
       || extent <= OtherExtent

And adjusting §20-22 accordingly.

I don't know why the current wording is the way it is but I think you
should take this in consideration in your proposal, as adapting
std::span seems easier than introducing a whole new type :)

I agree that messing with `span` would be easier than introducing `nspan`. However, I don't think even messing with `span` (in this respect) is a good idea.
IMHO it's clear that `span<int>` (with dynamic_extent) is the most correct type to use when your spans are of varying width. If you're using `span<int, 24>` in your API, it's because you intend to accept only spans of exactly 24 ints — no more and no less. If someone accidentally tries to pass you a `span<int, 42>` (with an extra 18 entries at the end that your API is going to silently ignore), that's a bug that should be caught at compile time!
If the caller knows what they're doing and really wants to pass "just the first 24 entries", they can write
  yourapi(mybigspan.subspan(0, 24));
  yourapi(std::span<int, 24>(mybigspan));
or probably any number of variations — the important thing is that they have to write that subspan-truncating operation explicitly in their code.
A span of 42 elements IS-NOT-A span of 24 elements; the domains of those two types are different; therefore the conversion between them should be explicit, not implicit.

HTH,
Arthur