Real World usage of D, Today (was Re: challenge #2: implement the varargs_reduce metafunction)

Kevin Bealer kevinbealer at gmail.com
Fri Jan 26 00:14:17 PST 2007


Andrei Alexandrescu (See Website For Email) wrote:
> kris wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>> [snip]
...
>>> 3. I want to increase community's awareness of the importance of 
>>> those tests for larger use cases, as well as gather ideas from the 
>>> community about how to overcome D's shortcomings in passing the tests.
...
> That being said, my view on what should be fixed in D is a bit 
> different. For example, as I said, one of my main foci is putting a lead 
> sarcophagus around "inout" before its radioactive waste affects too much 
> code that will become broken later. Also, implicit conversion rules will 
> change, and again I want to get that in ASAP so not too much code 
> suffers. And so on.
...
> Andrei


Well, since you mention it... I'm not positive that I'm thinking of the 
same type problem that you are, but when writing templates in D, I've 
wanted something like storageof(T) capabilities, but the way I imagine 
it, the ideal solution would be a bit different.

(Actually, I'm not sure exactly what problem inout causes that you are 
referring to as requiring lead, but moving on..)

I would prefer for the types passed to a template to carry a lot more 
info across, and let the user decide which parts to throw away.  You 
could call this a "strict" template, if you want backward compatibility 
(but it's early in D's template design so maybe we don't care).

I'm thinking that this (current) syntax:

template foo(T) {
    T plus(T x, T y) { return x + y; }
}

would be equivalent to:

strict template foo(T) {
     T.value plus(T.value x, T.value y) { return x + y; }
}

In a 'strict' template the type "T" would carry a lot of baggage.  It 
would know if T was constant (as in a local "const int x = 10"), or a 
constant view (maybe) whether it is an lvalue, rvalue, literal, 
known-at-compile-time, static array, result of arithmetic, etc.

I couldn't tell you the actual names and definitions of all of these 
attributes -- I imagine they could be added one at a time as the need 
arose, starting with an equivalent for "storageof".  [OT: I personally 
don't like the name storageof() because 'storage class' doesn't connote 
'inout' versus 'in' to me, I don't really think of those as storage.  I 
guess it comes from the idea of storing const items in R/O memory?)

What we normally think of as the "type" is called T.value in a strict 
template.  If you use "T" you get a whole lot more -- in fact, we might 
want to force the user to say "T.all" in this case.

In my view, what we have now, is a leaky abstraction - you get some type 
info but not a lot.  When you pass T into a template, you lose bits and 
pieces of what makes T work.

There would be two ways to manage the template definition - one is to 
get out each piece of 'type modification' data that you want to copy to 
the new type, using something like:

If T is "const long" (but not lazy), then:

   int foo(T.constness T.lazyness T.value x)

(becomes:  int foo(const long x))

Alternately, you could let users specify things like "in T" and the "in" 
overrides the "inout" if there was one.

Kevin



More information about the Digitalmars-d mailing list