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