Proposal - Revised Syntax for const and final

Janice Caron caron800 at googlemail.com
Sat Sep 8 08:21:04 PDT 2007


On 9/8/07, Daniel Keep <daniel.keep.lists at gmail.com> wrote:
>
> > final(S) s;
> > s = S();                /* Error */
> > s.x = 1;                /* OK* /
> > s.p = new int[1];       /* OK */
> > s.p[0] = 1;             /* OK */
>
> This is just silly.  You're completely ignoring how structures work.

Well, not ignoring as such, just ensuring that the same syntax works
for both classes and structures - much as we have s.member for both
structs and classes (and none of this -> malarchy as in C).

Whichever way you go, something's going to be "silly" from a certain
perspective.



> You *cannot* have a structure const and not have its members const; it
> doesn't make sense.

Well yeah, but bear in mind that that declaration used the (proposed)
final keyword, not the const keyword, so it's not _intended_ to
protect the members. The intent is just to allow structs to have the
same syntax as classes, that's all.

Basically, this possibility would be there just for completeness. I
include it only because the compiler can't eliminate it on the basis
of syntax alone. It could eliminate it at semantic analyis time, once
it knows what S is, I guess - in which can the compiler just makes it
an error.



> Now you're contradicting yourself.  You said that if something is final,
> you can't change *it*, but you *can* change it's members.

Fair enough. Call that a typo :)
(Though it was really a mistake).


> > TAIL constness --
> > In general, if a variable x is declared to be of type const*(T)
> > then x is mutable, but x.member is const (and x.member.member, etc.)
>
> So this is basically the *current* behaviour of const.

Well yeah. But the syntax would be different coz of the extra asterisk.



> > const*(S) s;
> > s = S();                 /* OK* /
> > s.x = 1;                 /* Error */
> > s.p = new int[1];        /* Error */
> > s.p[0] = 1;              /* Error */
>
> s = S(1, [1].dup);
>
> I just bypassed the const*-ness.

Well, I see what you mean, but it doesn't really violate the intent of
what I was getting at, which is kind of more like "You can change all
of it at once, but not just bits of it". Again, it's just a
side-effect of allowing identical syntax for structs and classes.



> > const*(int[][]) a;      /* a is array of const array of const int */
>
> Isn't this just const(int[])[]?  It makes me uneasy that there's a whole
> set of synonyms for a particular const type.

Yeah but that's only true because int[][] happens to be a type for
which you _can_ pull one level of indirection off by hand and rewrite
it outside the brackets.

In general, const*(T) a can't be rewritten in that way. It's only
because T happened to be a special case (an array) that you were able
to do that.

So yeah, if T is an array, you can indirect by removing one level of
[]. But what if it isn't? That's where the asterisk notation comes in.

So the price of generalised notation, is more than one way to write
things, in some cases.

Is that any worse than the current D2.0 scheme in which
const (int**) p;
const (int*)* p;
are two different ways of writing the same thing?


> Also, you've said nothing on invariant.  I assume you mean to treat
> invariant in the same way as const?

I was trying to keep things simple. :-)

I see no reason why it wouldn't work the same way, but <shrugs
shoulders> who knows? Maybe there's something I haven't thought of.



More information about the Digitalmars-d mailing list