Const by Default

David B. Held dheld at codelogicconsulting.com
Sun Jun 24 18:02:42 PDT 2007


I think an interesting point was brought up in the earlier CbD thread, 
which is specifically the issue of c'tors, and generally, the issue of 
passing mutable references.  So consider:

class MyObj
{
     this(MyClass a, MyClass b)
     {
         a_ = a;
         b_ = b;
     }
private:
     MyClass a_;
     MyClass b_;
}

With CbD, this code is incorrect.  Would you like to explain to a novice 
programmer why?  Now, let's try to fix it:

     this(ref MyClass a, ref MyClass b)
     {
         a_ = a;
         b_ = b;
     }

This code works, but now you have to explain to the student that even 
though classes are always passed by reference in D, you have to actually 
spell it out explicitly sometimes.  And further note that the only 
reason this form is not less efficient is because references to 
references are collapsed to simple references.  Otherwise, there would 
be an extra level of indirection here.  Here's another try:

     this(final MyClass a, final MyClass b)
     {
         a_ = a;
         b_ = b;
     }

Of course, you also have to explain why a and b are marked 'final' when 
they already are implicitly.  You have to tell the novice that you are 
specifying 'final' to turn off 'const'.  I expect that to elicit a: 
"Huh!??!" response.

Implicit actions are dangerous, which is a lesson we should have learned 
in spades from C++.  Every day I have to deal with scary smart pointer 
solutions that have each, in their infinite wisdom, exposed implicit 
conversion to T*, and have bent over backwards to try to prevent the 
types of programming mistakes that entailed.  I really don't see what is 
so evil about putting 'in' on your arguments.

There are a few other places where the absence of something means 
something.  Member functions, for instance.  You don't declare the 
'this' parameter, as it is implicit.  And yes, you can turn it off with 
'static'.  But it's not like member functions are declared as:

     member static int foo();

and spelling out:

     static int foo();

turns off the 'member' attribute.  That would be silly.  Another place 
where implicit stuff goes on is builtin type promotion.  Think signed 
vs. unsigned.  Who thinks the current rules are A Good Thing(TM) and 
cannot possibly be improved?

At one time, C had 'implicit int' return types.  C++ removed them.  Why? 
  Because 'implicit int' is A Bad Thing(TM).  C++ has implicit template 
instantiation.  D doesn't.  While there are probably people who would 
like D to have implicit template instantiation, it would make the 
language much more context-sensitive than it is now, because parsing 
would require symbol table lookups.  So if you look at many other areas 
where 'implicit X' has been tried, you see a lot of examples of bad 
features, some of which were actually removed.  Let's think very 
carefully and critically before we assume 'implicit in' is not one of 
them...it's only one char away from 'implicit int'. ;>

Dave



More information about the Digitalmars-d mailing list