November 30, 2007
Janice Caron wrote:
> Well, I'm still gunning for
> 
>     const (X)& x;
> 
> for mutable refs to const classes. Since I come from a C++ background,
> & means "reference of" to me, and this reads straightforwardly as "x
> is a reference to const X".
> 
> Of course, x would be a reference even /without/ the ampersand - such
> is the nature of classes in D. But writing it explicitly allows one to
> put it outside the brackets.

I like where this is going, but my guess is that when/if Walter ever introduces reference types, the syntax for reference-to-T will be "ref T" like the parameter signature rather than C++'s  "T&".

So if you're going peel off the hidden ref, I think you might should make it:

    ref X x --> const ref(T) x;
or          --> const (T)ref x;
or          --> ref const(T) x;

#3 seems pretty good to me.  But anyway no one knows what Walter will decide to do.

About references generally, one big difference between C++ references and D classes is that you can't reassign a C++ reference.
     // C++
     int& x = y;
     x = z;  /// error

In that sense, the C++ references themselves are always 'const' (aka head-const / final).
I seem to remember some example in Stroustrup that explained why this behavior was important.  But anyway, D's class references aren't like that, and it makes me wonder if more general D reference types in D would be like that.

--bb
November 30, 2007
Bill Baxter wrote:
> Janice Caron wrote:
>> Well, I'm still gunning for
>>
>>     const (X)& x;
>>
>> for mutable refs to const classes. Since I come from a C++ background,
>> & means "reference of" to me, and this reads straightforwardly as "x
>> is a reference to const X".
>>
>> Of course, x would be a reference even /without/ the ampersand - such
>> is the nature of classes in D. But writing it explicitly allows one to
>> put it outside the brackets.
> 
> I like where this is going, but my guess is that when/if Walter ever introduces reference types, the syntax for reference-to-T will be "ref T" like the parameter signature rather than C++'s  "T&".
> 
> So if you're going peel off the hidden ref, I think you might should make it:
> 
>     ref X x --> const ref(T) x;
> or          --> const (T)ref x;
> or          --> ref const(T) x;
> 
> #3 seems pretty good to me.  But anyway no one knows what Walter will decide to do.
> 
> About references generally, one big difference between C++ references and D classes is that you can't reassign a C++ reference.
>      // C++
>      int& x = y;
>      x = z;  /// error

Er. Not 'error' per se, it just doesn't rebind x, it modifies y.

> In that sense, the C++ references themselves are always 'const' (aka head-const / final).
> I seem to remember some example in Stroustrup that explained why this behavior was important.  

I remembered.  You can't reassign them because it's ambiguous whether you want to make x just refer to the new thing or call the opAssign on the previously bound thing.  Ok, so D classes get around this by eliminating opAssign for classes and saying you can *only* rebind the reference.  But I don't think that will fly for references to structs or built-in value types.

--bb
November 30, 2007
> So if you're going peel off the hidden ref, I think you might should make it:
>
>     ref X x --> const ref(T) x;
> or          --> const (T)ref x;
> or          --> ref const(T) x;
>
> #3 seems pretty good to me.  But anyway no one knows what Walter will decide to do.

Good point here.

Here's another idea.  If we reverse the meaning of const(X) then we could do this:

const X x;  // all const
const(X) x; // data const, ref mutable
X const x; // data mutable, ref const


November 30, 2007
On Fri, 30 Nov 2007 15:27:20 -0600, Craig Black wrote:

> 
> Here's another idea.  If we reverse the meaning of const(X) then we could do this:
> 
> const X x;  // all const
> const(X) x; // data const, ref mutable
> X const x; // data mutable, ref const


I like this, nice and clear.
++vote.
November 30, 2007
Craig Black wrote:

> 
> "Janice Caron" <caron800@googlemail.com> wrote in message news:mailman.206.1196453000.2338.digitalmars-d@puremagic.com...
>> Well, I'm still gunning for
>>
>>    const (X)& x;
>>
>> for mutable refs to const classes. Since I come from a C++ background, & means "reference of" to me, and this reads straightforwardly as "x is a reference to const X".
>>
>> Of course, x would be a reference even /without/ the ampersand - such is the nature of classes in D. But writing it explicitly allows one to put it outside the brackets
> 
> I now better understand why you proposed this syntax.  I guess it's not so bad.  I can't think of anything better.

Technically, I proposed the syntax.  Janice didn't like it at first but has now come full circle.

I've had some second thoughts about stuff, but I'm still able to convince myself that a novel syntax for rebindable constant objects is best.

Here's what I consider to be requirements:
  const(...) must mean that everything within the parens is constant
  "const X" and "const(X)" must mean the same thing
  Rebindable constant objects are important to have
  const(X) foo(){...} should mean that what it returns is constant.
  "non-rebindable const(X) x = foo();" should be allowed
  "rebindable const(X) x = foo();" should be allowed
  "const(X) foo(){non-rebindable const(X) x; return x;}" should be allowed
  "const(X) foo(){rebindable const(X) x; return x;}" should be allowed.

From those requirements, "const(X) x;" must mean that x can not be rebound.
Using "const(X)& x;" for a rebindable definition seems to be the best I can
come up with.

Do people disagree with any of the requirements I listed?  Most are just sanity requirements, but may not have general agreement.  Beyond that, is there a better for for a rebindable definition?
November 30, 2007
On Fri, 30 Nov 2007 15:27:20 -0600, Craig Black wrote:

>> So if you're going peel off the hidden ref, I think you might should make it:
>>
>>     ref X x --> const ref(T) x;
>> or          --> const (T)ref x;
>> or          --> ref const(T) x;
>>
>> #3 seems pretty good to me.  But anyway no one knows what Walter will decide to do.
> 
> Good point here.
> 
> Here's another idea.  If we reverse the meaning of const(X) then we
> could do this:
> 
> const X x;  // all const
> const(X) x; // data const, ref mutable X const x; // data mutable, ref
> const

On that note, we could try to keep Janice's idea that const X = const(X) and Adam's explanation of compile time function.

const X x; // data const
X const x; // ref const
const(X x); // both const

This would mean that const(T) takes a type T and returns a constant of it. Since in the last one, const(X x) takes a class and ref it will return a const of both. Equivalents of the above to help demonstrate the concept.

const(X) x; // data const
X const(x); // ref const
const(X) const(x); // both const
December 01, 2007
Adam D. Ruppe, el 30 de noviembre a las 13:38 me escribiste:
> int a;
> Adds an entry to the compiler's variable table named 'a' that references
> memory that is an int.
> 
> const(int) a;
> Add an entry named 'a' that references memory that is a constant int. The
> const() CTF takes the type int and returns a new type that is a constant int.
> 
> const int a;
> Add a *constant* entry named 'a' that references memory that is a mutable
> int.

But now you lost the idea of transitive constness (if your compile-time pointer is const, the value it points to should be const). This doesn't break your "model" if you think as if D works like Python, where int are inmutables, but you can rebind the variable (your compile-time pointer).

Then:
const int a = 1;
means "I have a variable named 'a' that points to some int that has the
value 1 and I can't change where it points to (I can't rebind it)".

a = 2; is an error

const(int) b = 1;
means "I have a variable named 'b' that points to some int, conceptually
the same int as 'a', because there is no need to have more than 2
inmutable ints with the same value in the program, but I can change where
'b' points to (I can rebind it).".

so b = 2; is ok

So graphically:

     +---+
a -> | 1 | <- b
     +---+

and after b = 2;

     +---+         +---+
a -> | 1 |    b -> | 2 |
     +---+         +---+

Of course this is a "conceptual" model, otherwise there would not be value passing and must be a reference internall, which I think is not that efficient ;)

This is basically what happens with pointers and the values they point to.

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
Did you know the originally a Danish guy invented the burglar-alarm unfortunately, it got stolen
December 01, 2007
On 11/30/07, Denton Cockburn <diboss@hotmail.com> wrote:
> > const X x;  // all const
> > const(X) x; // data const, ref mutable
>
> I like this, nice and clear.

I don't think I'll ever like any scheme in which const(X) != const X.
December 01, 2007
On 11/30/07, Jason House <jason.james.house@gmail.com> wrote:
> Craig Black wrote:
> Technically, I proposed the syntax.  Janice didn't like it at first but has
> now come full circle.

That's right. I think my earlier attempt was something like "const(X)ref" or "ref const(X)". I came full circle and now fully support Craig's idea, largely because I think there may come a time in the future when D has C++-style references. If and when that day comes, "&" will be preferable to "ref" for the same reason that "*" is preferable to "ptr". If it's /only/ classes we're talking about, it's no big deal either way, but if referencing gets more ubiquitious in the future, less typing => better.

So Craig gets the kudos for invention on this one. Nice one, Craig!
December 01, 2007
On Sat, 01 Dec 2007 06:35:46 +0000, Janice Caron wrote:

> On 11/30/07, Jason House <jason.james.house@gmail.com> wrote:
>> Craig Black wrote:
>> Technically, I proposed the syntax.  Janice didn't like it at first but
>> has now come full circle.
> 
> That's right. I think my earlier attempt was something like "const(X)ref" or "ref const(X)". I came full circle and now fully support Craig's idea, largely because I think there may come a time in the future when D has C++-style references. If and when that day comes, "&" will be preferable to "ref" for the same reason that "*" is preferable to "ptr". If it's /only/ classes we're talking about, it's no big deal either way, but if referencing gets more ubiquitious in the future, less typing => better.
> 
> So Craig gets the kudos for invention on this one. Nice one, Craig!

Based off of what you said in my other post, Walter will not change D's transitivity, Craig's proposal violates this. As a lot of the discussion here has suggested a solution for having a const ref with mutable data. So if I am correct then the real problem becomes with,

const(char)* foo == const(char*) foo
const(char)* foo != const char* foo
and thus
const X x != const(X) x

That is to say that const() means the reference can be rebound and const does not.

In this case I will re-propose Adam's idea to explain it that const() returns a constant of what is inside.

const TYPE * foo  // *foo immutable, foo mutable
const(TYPE) * foo // same as above
const(TYPE *) foo // foo and *foo immutable, but foo can be rebound
const(TYPE * foo) // nothing mutable, no rebinding of foo
TYPE * const foo  // Same as above

It would appear this meets at least most of the complaints const() does not have a special meaning, everything can be achieved with one const keyword, transitivity holds, no ambiguity, everything in const() is const. The only problem is that it would break all previous code, unless you assume const grabs everything after it so that the first and last are the same.