`ref T` should be a type!!

Manu turkeyman at gmail.com
Mon Apr 1 01:19:41 UTC 2019


On Sun, Mar 31, 2019 at 5:20 PM Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> On 3/31/2019 3:48 PM, Manu wrote:
> >> Even in C++ despite of all its silliness, T& is a type and can be
> >> used as a template argument.
> >>
> >> Can the language be changed to resolve this problem?
> >
> > 1. I couldn't possibly agree with you more!!! Sadly that's not how it is.
>
> Although ref can be captured with C++ templates, it isn't really a type. For
> example, you cannot create a pointer to a ref. Furthermore, the spec for it is
> crammed with wacky special cases to make it behave like a storage class instead
> of a type. I defy anyone to give a list of cases when C++ ref is inferred and
> when it is not, and if anyone did, I'm sure it would be wrong. Yes, it's that bad.

Are you saying that it's impossible to design a solution where ref is
part of the type and that's less complex than C++?
Is the complexity is that ecosystem inherent, or is it somewhat
informed by backwards-compatibility, and other C++ design constraints?

The fact that I can write `struct Ref(T)` and that it propagates the
type system in a natural way suggests to me that the design is not
impossible.


> > Writing that code is like stabbing myself in the hands with rusty
> > forks...
>
> I'm convinced that if C++ ref didn't exist, and we added it to D, you'd hate it :-)

I think you probably have me backwards... irrespective of C++, and
there was some discussion about ref vs pointers, I would push 110% for
ref and eliminate pointers entirely.
I would be much happier to write this hack in the event I need a
pointer, than to hack around ref as I do today:

struct Pointer(T)
{
  size_t addr;
  this(ref T val) { addr = __traits(addressOf, val); }
  ref T get() { return __traits(addressAsRef, T, addr); }
  alias get this;

  Pointer!T opBinary(string op : "+")(size_t offset) { Pointer!T r;
r.addr = addr + offset * T.sizeof; return r; }
  // etc...
}

Pointers are mostly useless and unsafe at best, especially when arrays
are a first-class type.


> > I feel emotionally unstabilised, but it can solve your
> > problems in various applications.
>
> Please show a use case. I can't think of one.

A use case for propagating ref in the type? You can't imagine why a
template argument might want to distinguish `int` and `ref int`?

I don't know how you've never found yourself static-if-ing on ref-ness
of stuff in every bit of functional meta you've ever written. Ref
creates an out-of-language (we have no language features to interact
with 'storage class') suite of conditions that I frequently have to
wrangle my way through.
We have strong language mechanisms to reason about the type system,
there is no language to reason about storage class that's not a kludge
of awkward hacks and ugly meta utilities.


More information about the Digitalmars-d mailing list