Am I getting this all right?

Bill Baxter dnewsgroup at billbaxter.com
Wed Dec 13 17:30:31 PST 2006


Jason House wrote:
> I'm kind of doing a trial by fire method to learn D and how it works... I'm
> taking an existing open source project and converting it over.  Here's the
> stuff that I've found / questions that I have.

Great.  Welcome.

> Thanks in advance for all the thoughtful responses.  I know this is a long
> post!  I've worked through the issues to get working code, but I think my
> issues will be hit by others.
> 
> It seems that DTL and minTL [...]

Never tried either one, so can't help you there.

> I know of no way in d to provide a const qualifier.  It seems like the concept
> purely doesn't exist.  minTL appears to have a workaround where it templates
> itself on a boolean value, and simply doesn't publish certain functions.  When
> will a real const qualifier get added to the language?  It seems really
> strange that a language that adds all kinds of contract programming wouldn't
> use const qualifiers / const types.

That's right.  D's const is limited to things whose value can be 
determined at compile time.  So no const function parameters, for 
instance.  I agree it is a bit odd.  In particular I'd really like to 
have 'const inout' parameters for functions (though that actual 
nomenclature is nonsense).  Right now declaring a parameter to be 'inout 
T' is the only way to make sure a huge value type T doesn't get copied 
on the stack.  'inout' is basically a T& in C++ terms.  'const T&' is 
probably more common in C++ than plain 'T&'.  Sadly, D has no equivalent 
for it.

My vote would be for an 'refin' or 'inref' parameter type in addition to 
the existing 'in', 'out', and 'inout' flavors.

I think the reason D doesn't have it is just because C++ code gets 
pretty ugly with all those consts everywhere.  Then there's 
const-correctness hell, when you decide to change one method to const 
and suddenly there's a ripple effect across your whole application. 
Until you get to the point where you discover that some 3rd party code 
out of your control is not const-correct and you ultimately resort to 
const_cast<>s.

I guess I'm used to it, though.  :-) That doesn't seem such a bad thing 
to me if it results in a program that more clearly documents which 
things can be modified.  I'm certainly glad that D is not Fortran where 
every parameter is basically inout, and you have to read the 
documentation to see if what you pass in is going to be clobbered or not.

> After banging my head on printing stuff for a long time, I've come to a few
> conclusions:
> * The C++ equivalent to std::ostream& operator << (std::ostream &out, const
> type &x) does not exist

I think std.stream.OutputStream.write is the closest there is.  But 
mainly you can't overload operators outside of classes in D.  And also I 
think template lookup across modules doesn't work.  What I recall being 
the killer the last time I brought up something like this was that 
Walter says it's too tricky to get Koenig lookup working.  I'm not 
really sure what the deal is, but I think D is going to need it 
eventually.  Correct me if I'm wrong, folks, but right now the only way 
to do things like C++'s operator<< (the compile-time polymorphism 
functionality, not the syntax) is to have an exhaustive list of static 
if, else static if, ... cases inside a template.  Thus users can't add 
their own overrides in a different module.

> * Custom types use the toString property

Yes.

> * Enums do not (and can not) have a toString property

I guess not.  But of course you can make a toString non-property for 
your enum.  writefln(toString(myEnum)) instead of writefln(myEnum).

> * I have found no way to determine (in a templated class) if a type is
> printable or not.  static if(is(typeof(T))) comes close, but my very first
> test using ints failed.

You mean printable as in writefln(x) will work on it?  Hmm.  That is 
kinda tricky.  I think there's a way to do it, but it will likely 
involve lots of static if's checking one-by-one for types that are 
printable.  Ultimately, though, what's "printable" boils down to what 
things std.format.doFormat supports, and that's ultimately only 
determinable at runtime.

> The special unittest member function doesn't get built in with -unittest
> unless the actual class is used in some way (and then one copy of the unittest
> funciton gets run for each type).  I'd really like to see some way for this to
> work.  for example, class foo(T){ ... unittest{ foo!(int) sample; ...} } does
> not run unless other code instantiates foo!(U)

That sounds like a bug.  I didn't even realize you could put unittests 
inside of classes.  All the code I've seen has the unittests outside of 
the class.

> In my early efforts at doing operator overloading, I wrote opCmp and then was
> shocked when my unit test showed that == didn't even call opCmp.  It silently
> did something wrong.  This seems like a gotcha built into the language that
> should probably get remedied.

Like what?  I'm not really to up on opEquals/opCmp.  Should you get a 
warning if you only override opCmp?  Or an error?

> I couldn't find a way to reinitialize a variable back to a default value...
> For example class foo(T){ T[] bar; void func(){bar[3] = new T();} } won't
> compile.  I'm not too sure why this is the case.

bar[3] = T.init is what you need for a value type.

--bb


More information about the Digitalmars-d-learn mailing list