RAII, value classes and implicit conversion

Boris Kolar boris.kolar at globera.com
Wed Nov 15 00:54:56 PST 2006


== Quote from Bill Baxter (dnewsgroup at billbaxter.com)'s article
(immutable structs)
> But seriously const applied to instances seems sufficient to me.  Why
> restrict the utility of the class in that way?  At least you need to
> find a better example than Point to illustrate your case.

Small utility structs should usually be immutable - it's simply a matter
of good design. A few seconds on Google gives enough reasons for immutable
structs/classes:
http://www-128.ibm.com/developerworks/java/library/j-jtp02183.html

> I'd like this too -- at least constructors.  But Walter is against
> destructors since (IIUC) it creates complications when passing structs
> as arguments or when they get created as implicit temporaries by the
> compiler.  Something like that.

C++ has no problems with destructors, therefore it should be possible to
implement them in D as well.

> However, if you add constructors to structs what's the syntax for use
> going to be?  Personally I can't think of anything more natural than
> MyStruct(a,b,c).    So I think it would have to act just like a static
> opCall.

Yes, exactly what I had in mind.

> Something like a File shouldn't be a struct.  If you're going to be
> doing file IO, then probably the speed hit of having to do one dynamic
> allocation is not important.

Of course. But this was not meant to be a real world example. Basically,
I don't see much difference between structs and classes except that
structs don't have VMT table. Not having VMT table can be (sometimes) usefull,
especially if your struct mirrors layout of some other structure. And it
makes them a bit "safer", because you can't accidently override struct's
methods (which reminds me of another wish: compiler should at least warn when
you override methods without explicit 'override').

> Don't know about that.  I think implicit conversion would only make
> sense for pointers to structs.  But maybe I'm missing your point.

Implicit conversions make just as much sense as inheritance. Of course, indirect
implicit conversions can be ambigous, but there are algorithms to detect this. For
example, consider implicit conversions of "big" versions of numbers:
  BigCardinal -> BigInteger -> BigRational

A relatively simple rule about implicit conversion should be:
- implicit conversion is possible if the shortest conversion path to desired
type is not ambigous

> So this is just an alternative to 'override'?  If so I like it.  I find
> I always end up putting a comments in my code anyway like:

Explicit implementation is more than just 'override'. You can, for example,
implement two different interfaces with the "same" method, like that:

  interface Foo {
    int foo();
  }
  interface Bar {
    char[] foo();
  }
  class FooBar: Foo, Bar {
    int Foo.foo() { ... }
    char[] Bar.foo() { ... }
  }

Also, you can implement all methods at once with delegation:

  class Foo: Bar {
    this.Bar { // will implement all Bar's methods
      return getBar();
    }
  }

> > Value classes can easily support deterministic finalization, because no cycles are
> > possible (without hacking, anyway) and simple reference counting is sufficient.
> This is just different syntax for "auto class Foo" as far as I can tell.

Additionally, const classes are immutable, so no cyclic references are possible,
therefore
implementing deterministic finalization is much easier (for non-const classes,
compiler
would have to do escape analysis, which I suspect is not an easy task).

> > 2.3 Custom allocators
> > ...
> >     Foo foo = new(myAllocator) Foo();
> I thought this was possible already.

Yes, but you have to encode allocation strategy in class. So, in this case, Foo must
redefine the 'new' operator. My suggestion was that allocation strategy can be
redefined
for all (including existing) classes.

> > Another (minor) suggestion is allowing method declarations without '()':
> Eh, I don't that as much of a gain, and it would make grepping for
> function definitions a little bit harder.

Yes, not much gain. Since you can already omit '()' everywhere except in declarations,
I thought it would be more consistent to simply state that all '()' are optional.




More information about the Digitalmars-d mailing list