December 07, 2010
Michel Fortin Wrote:
> The point is that the 'ref' in in the 'b' and 'c' variable declaration has the effect of changing the ref from B and C from const to mutable, even for B where the ref was explicitly specified to be const. I was wondering if some people would find that surprising, but if I understand you well that's what you expect when seeing this, right?

I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations.

I think the array case would be missed. I'm not sure what people would think of the template case, especially when it pops up in code such as foo!(typeof(x)). If ref isn't a storage class, then generic programmers will need an equivalent to unqual that only strips the outer-most ref. As a storage class typeof would not return the ref. How do templates work with your patch?
December 07, 2010
On 2010-12-07 09:05:20 -0500, Jason House <jason.james.house@gmail.com> said:

> Michel Fortin Wrote:
>> The point is that the 'ref' in in the 'b' and 'c' variable declaration
>> has the effect of changing the ref from B and C from const to mutable,
>> even for B where the ref was explicitly specified to be const. I was
>> wondering if some people would find that surprising, but if I
>> understand you well that's what you expect when seeing this, right?
> 
> I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations.
> 
> I think the array case would be missed. I'm not sure what people would think of the template case, especially when it pops up in code such as foo!(typeof(x)). If ref isn't a storage class, then generic programmers will need an equivalent to unqual that only strips the outer-most ref. As a storage class typeof would not return the ref. How do templates work with your patch?

From my tests, templates work as they should. For instance, I can easily call std.algorithm.sort on an array of const(Object)ref. Which brings the question: how do you do that if 'ref' is a storage class? :-)

The way I implemented the feature in the compiler is that I added the notion of head-modifiers for types. For most types, head-modifiers are just a pointer to the regular modifiers, so they're always identical. But for a class type, encountering a 'ref' suffix changes the head-modifiers to match those applied to the suffix. Then when declaring a variable, when the compiler deduces the storage class for that variable from its type, I changed it so it checks the head-modifiers of the type instead of its regular modifiers. A few other tweaks like that were required to make it work with foreach and array ops, but the end result is a very small change to the compiler that fits reasonably well within the type system.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 07, 2010
On Tue, 07 Dec 2010 09:05:20 -0500, Jason House <jason.james.house@gmail.com> wrote:

> Michel Fortin Wrote:
>> The point is that the 'ref' in in the 'b' and 'c' variable declaration
>> has the effect of changing the ref from B and C from const to mutable,
>> even for B where the ref was explicitly specified to be const. I was
>> wondering if some people would find that surprising, but if I
>> understand you well that's what you expect when seeing this, right?
>
> I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations.

IIUC, I think ref in this case is a type modifier.  There are other examples of keywords that are both storage classes and type modifiers (const, shared).

-Steve
December 07, 2010
On 12/6/10 9:56 AM, Michel Fortin wrote:
> On 2010-12-06 00:16:27 -0500, Graham St Jack
> <Graham.StJack@internode.on.net> said:
>
>> First, I have to say that it is wonderful that someone is taking a
>> serious look at this area again, and even better, you have come up
>> with a compiler patch to make it happen!
>>
>> Some questions (assuming your patch or something like it gets into dmd):
>>
>> Does this mean that I would be able to write this:
>> immutable(Foo)ref foo; // create a reference
>> foo = new immutable(Foo)(); // re-bind it (not sure about "new" syntax
>> for immutables)
>
> That's the whole point yes. This syntax works with my patch. :-)
>
>
>> Are there any other show-stopping syntax issues that are holding up
>> widespread adoption/rollout of const-correctness?
>
> Surly there are others issues to solve. But this one is the one I kept
> falling into when trying to use immutable objects in my code some time ago.
>
>
>> What do Walter and Andrei think?
>
> That I'd like to know.

I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch. Also providing precompiled binaries would help people who don't care to build their own compiler.

Andrei
December 07, 2010
On 12/7/10 7:05 AM, Michel Fortin wrote:
> On 2010-12-07 09:05:20 -0500, Jason House <jason.james.house@gmail.com>
> said:
>
>> Michel Fortin Wrote:
>>> The point is that the 'ref' in in the 'b' and 'c' variable declaration
>>> has the effect of changing the ref from B and C from const to mutable,
>>> even for B where the ref was explicitly specified to be const. I was
>>> wondering if some people would find that surprising, but if I
>>> understand you well that's what you expect when seeing this, right?
>>
>> I've been wondering if it makes more sense for 'ref' to be a storage
>> class rather than some kind of type constructor. Doing that would make
>> the typedef's with ref be illegal. It'd also make foo!(const(T) ref)
>> be illegal as well as (const(T) ref)[]. As a storage class, it can
>> only be added to variable declarations.
>>
>> I think the array case would be missed. I'm not sure what people would
>> think of the template case, especially when it pops up in code such as
>> foo!(typeof(x)). If ref isn't a storage class, then generic
>> programmers will need an equivalent to unqual that only strips the
>> outer-most ref. As a storage class typeof would not return the ref.
>> How do templates work with your patch?
>
>  From my tests, templates work as they should. For instance, I can
> easily call std.algorithm.sort on an array of const(Object)ref.

Does it work on a general random-access range? Generally, does the feature have a solution for all issues discussed?

Andrei
December 07, 2010
On 2010-12-07 11:15:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> On 12/7/10 7:05 AM, Michel Fortin wrote:
>> From my tests, templates work as they should. For instance, I can
>> easily call std.algorithm.sort on an array of const(Object)ref.
> 
> Does it work on a general random-access range?

It should. Let's try:

	auto array = new const(Object)ref[12];
   auto range = retro(array);
	sort!("cast(void*)a < cast(void*)b")(range);

Compiles and runs with no error. Also, if I put actual objects in the array, I can see they're properly sorted.


> Generally, does the feature have a solution for all issues discussed?

It fixes all issues about mutable references to const classes that I can think of. But it's hard to see if I missed something without a proper checklist.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 07, 2010
On 2010-12-07 11:09:50 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> On 12/6/10 9:56 AM, Michel Fortin wrote:
>> On 2010-12-06 00:16:27 -0500, Graham St Jack
>> <Graham.StJack@internode.on.net> said:
>> 
>>> First, I have to say that it is wonderful that someone is taking a
>>> serious look at this area again, and even better, you have come up
>>> with a compiler patch to make it happen!
>>> 
>>> Some questions (assuming your patch or something like it gets into dmd):
>>> 
>>> Does this mean that I would be able to write this:
>>> immutable(Foo)ref foo; // create a reference
>>> foo = new immutable(Foo)(); // re-bind it (not sure about "new" syntax
>>> for immutables)
>> 
>> That's the whole point yes. This syntax works with my patch. :-)
>> 
>> 
>>> Are there any other show-stopping syntax issues that are holding up
>>> widespread adoption/rollout of const-correctness?
>> 
>> Surly there are others issues to solve. But this one is the one I kept
>> falling into when trying to use immutable objects in my code some time ago.
>> 
>> 
>>> What do Walter and Andrei think?
>> 
>> That I'd like to know.
> 
> I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch.

The patch itself is documented in the bug tracker where it resides. It lacks some details about the internal implementation, but beside that I'm not sure how more elaborate the documentation should be. D's documentation doesn't tell about every corner case of the language either.
<http://d.puremagic.com/issues/show_bug.cgi?id=5325>


> Also providing precompiled binaries would help people who don't care to build their own compiler.

I can easily provide one for Mac OS X. Can someone else build it for Linux and Windows?


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 07, 2010
On 2010-12-07 12:54:49 -0500, Michel Fortin <michel.fortin@michelf.com> said:

> On 2010-12-07 11:09:50 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
>> On 12/6/10 9:56 AM, Michel Fortin wrote:
>>> On 2010-12-06 00:16:27 -0500, Graham St Jack
>>> <Graham.StJack@internode.on.net> said:
>>> 
>>>> First, I have to say that it is wonderful that someone is taking a
>>>> serious look at this area again, and even better, you have come up
>>>> with a compiler patch to make it happen!
>>>> 
>>>> Some questions (assuming your patch or something like it gets into dmd):
>>>> 
>>>> Does this mean that I would be able to write this:
>>>> immutable(Foo)ref foo; // create a reference
>>>> foo = new immutable(Foo)(); // re-bind it (not sure about "new" syntax
>>>> for immutables)
>>> 
>>> That's the whole point yes. This syntax works with my patch. :-)
>>> 
>>> 
>>>> Are there any other show-stopping syntax issues that are holding up
>>>> widespread adoption/rollout of const-correctness?
>>> 
>>> Surly there are others issues to solve. But this one is the one I kept
>>> falling into when trying to use immutable objects in my code some time ago.
>>> 
>>> 
>>>> What do Walter and Andrei think?
>>> 
>>> That I'd like to know.
>> 
>> I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch.
> 
> The patch itself is documented in the bug tracker where it resides. It lacks some details about the internal implementation, but beside that I'm not sure how more elaborate the documentation should be. D's documentation doesn't tell about every corner case of the language either.
> <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
> 
> 
>> Also providing precompiled binaries would help people who don't care to build their own compiler.
> 
> I can easily provide one for Mac OS X. Can someone else build it for Linux and Windows?

Here is a Mac OS X build. It's based on SVN revision 780 (two days old). It's a debug build so it might run a little slower than release versions of the compiler.
<http://michelf.com/docs/d/dmd-rev780-objconst.zip>

You should be able to use it with druntime either from DMD 2.050 or the latest SVN (nothing needs to be patched in druntime). Phobos unittests will pass (except for Rebindable tests, Rebindable itself works fine but some assertions the unittests aren't expecting the new type).

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 08, 2010
Michel Fortin wrote:
> After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch.
> <http://d.puremagic.com/issues/show_bug.cgi?id=5325>

I think it's great that you're trying this out. I failed at getting tail const to work. I don't think it can work, but I might be wrong.
December 08, 2010
On 2010-12-08 03:43:45 -0500, Walter Bright <newshound2@digitalmars.com> said:

> Michel Fortin wrote:
>> After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch.
>> <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
> 
> I think it's great that you're trying this out. I failed at getting tail const to work. I don't think it can work, but I might be wrong.

Is there something I can do to convince you this patch works? Because it does. There is still some rough edges for which I wasn't sure what was the best solution -- head-modifiers not reflected in TypeInfo or with is(T == const) -- but they're relatively minor and easy to fix once we know what we want.

By the way, I pushed this into a separate branch in my dmd-objc git repository (this branch does not include the Objective-C-related changes). So you can get the source with the patch pre-applied this way:

	git clone http://git.michelf.com/dmd-objc/
	cd dmd-objc
	git checkout objconst

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/