December 08, 2010
Andrei Alexandrescu Wrote:
> >> What do Walter and Andrei think?
> >
> > That I'd like to know.
> 
> I think actually offering a patch is a great initiative!

Yeah, it's great initiative. Working prototypes really make it easy to fully evaluate an option and require almost no effort to formally adopt.


> I think the syntax is not all that intuitive, but it's great to experiment with.

Really? Back when this stuff was actively being bikeshedded, it was my favorite syntax for this feature. Since then, a somewhat conflicting feature was added: auto ref. I saw some posts recently about @tail being someone else's favorite, but I personally like the ref syntax better. Basically, reference types have an implicit ref which you can manually specify to disambiguate your intention with const stuff.

December 08, 2010
Michel Fortin wrote:
> 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.

I haven't been able to look at it yet.

But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test:

1. auto variable declarations
2. typeof
3. mangleof
4. template type deduction
5. interaction with inout
6. arrays of, pointers to, functions returning
7. tail const functions
8. tail immutable
9. tail shared const
10. tail inout
December 08, 2010
On 2010-12-08 14:17:10 -0500, Walter Bright <newshound2@digitalmars.com> said:

> I haven't been able to look at it yet.
> 
> But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test:
> 
> 1. auto variable declarations
> 2. typeof
> 3. mangleof
> 4. template type deduction
> 5. interaction with inout
> 6. arrays of, pointers to, functions returning
> 7. tail const functions
> 8. tail immutable
> 9. tail shared const
> 10. tail inout

I've already tested most of this, but I'll make sure my unit tests cover it all.

That said, what's a "tail const function"?

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

December 08, 2010
On Wed, 08 Dec 2010 15:21:38 -0500, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2010-12-08 14:17:10 -0500, Walter Bright <newshound2@digitalmars.com> said:
>
>> I haven't been able to look at it yet.
>>  But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test:
>>  1. auto variable declarations
>> 2. typeof
>> 3. mangleof
>> 4. template type deduction
>> 5. interaction with inout
>> 6. arrays of, pointers to, functions returning
>> 7. tail const functions
>> 8. tail immutable
>> 9. tail shared const
>> 10. tail inout
>
> I've already tested most of this, but I'll make sure my unit tests cover it all.
>
> That said, what's a "tail const function"?

it's not necessary to have a tail-const function for a class.  The only advantage of having a tail-const function would be if you wanted to change the 'this' pointer, which you shouldn't do anyways.

tail-const for a struct would then require tail-const functions (and would require being able to mark member functions to pass 'this' by value), but I don't think your patch addresses those.

Also note that inout doesn't really work at all, so I wouldn't bother testing anything with inout.

-Steve
December 08, 2010
Michel Fortin wrote:
> That said, what's a "tail const function"?


applying tail const to a function type
December 09, 2010
On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2@digitalmars.com> said:

> Michel Fortin wrote:
>> That said, what's a "tail const function"?
> 
> applying tail const to a function type

You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works.

Would you like some documentation on the changes I've made? This might be useful when reviewing it.

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

December 09, 2010
Michel Fortin Wrote:

> On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2@digitalmars.com> said:
> 
> > Michel Fortin wrote:
> >> That said, what's a "tail const function"?
> > 
> > applying tail const to a function type
> 
> You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works.

He might mean functions and delegates... A rebindable function pointer, etc...
He might also mean a member function that is "const ref". If I understand your design, I don't those are allowed.

December 09, 2010
Michel Fortin wrote:
> On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2@digitalmars.com> said:
> 
>> Michel Fortin wrote:
>>> That said, what's a "tail const function"?
>>
>> applying tail const to a function type
> 
> You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works.
> 
> Would you like some documentation on the changes I've made? This might be useful when reviewing it.

A test suite for it would be better.
December 10, 2010
It is nice that Michel Fortin made the effort to propose a patch trying to address the ability to rebind const objects.

Looking at the "uglification" of my code to support const, I saw that many cases I actually had a unique type, or partially unique type.

There are several examples of similar attempts, like linear types, or various uniqueness types systems (more or less related to the Clean example).
It is known that some uniqueness settings are equivalent to shared, so maybe using uniqueness with const might be meaningful.

This is a difficult topic, as pushing those concepts into the type system is always tricky, and the consequences of various choices are often non obvious, anyway here is what I thought.

If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code.

Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects).

In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer.

I did also think about having a front_unique attribute that can be applied to any local variable or argument that would make it tail const in the sense discussed previously, and still implicitly castable to full const.
In that case the situation is more complex (one should ensure that local references cannot spill out, otherwise a full const is needed, and for immutable, making it immutable is "irreversible".
The front_unique property can almost always be checked by the compiler, but activating it implicitly would have effects that would probably deemed surprising by the programmer (front_unique immutable objects would be rebindable).
Thus I am not sold on front_unique, but I still find it interesting, due to its relationship with tail const.

Fawzi

December 10, 2010
Fawzi Mohamed wrote:

> If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code.
> 
> Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects).
> 
> In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer.

Any mutable object returned from a strongly pure function, is guaranteed to be unique.