tail const

Steven Schveighoffer schveiguy at yahoo.com
Fri Dec 3 17:22:45 PST 2010


On Fri, 03 Dec 2010 19:06:36 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 12/3/10 5:17 PM, Steven Schveighoffer wrote:
>> On Thu, 02 Dec 2010 17:02:42 -0500, Michel Fortin
>> <michel.fortin at michelf.com> wrote:
>>
>>> On 2010-12-02 16:14:58 -0500, "Steven Schveighoffer"
>>> <schveiguy at yahoo.com> said:
>>>
>>>> On Thu, 02 Dec 2010 07:09:27 -0500, Michel Fortin
>>>> <michel.fortin at michelf.com> wrote:
>>>>> My only concern with the "const(Object)ref" syntax is that we're
>>>>> reusing 'ref' to denote an object reference with different
>>>>> properties (rebindable, nullable) than what 'ref' currently stands
>>>>> for. But it remains the best syntax I've seen so far.
>>>> Where it would be beneficial is in mimicking the tail-const
>>>> properties of arrays in generic ranges.
>>>> I have a container C, which defines a range over its elements R.
>>>> const(R) is not a usable range, because popFront cannot be const. So
>>>> now I need to define constR, which is identical to R, except the
>>>> front() function returns a const element.
>>>> So now, I need the same for immutable.
>>>> And now I need to triplicate all my functions which accept the
>>>> ranges, or return them.
>>>> And I can't use inout(R) as a return value for ranges.
>>>> If you can solve the general problem, and not just the class
>>>> tail-const, it would be hugely beneficial.
>>>> My thought was that a modifier on const itself could be stored in the
>>>> TypeInfo_Const as a boolean (tail or not), and the equivalent done in
>>>> dmd source itself.
>>>
>>> I'm not sure I get the problem. Can you show me in code?
>>
>> Here is an example range from dcollections (well, at least the pertinant
>> part), for a linked list:
> [snip analysis]
>> @tail inout(Range) opSlice() inout
>> {
>>   ...
>> }
>
> I was about to post a similar analysis, but my suggested conclusion is  
> very different: in my humble opinion, we must make-do without tail  
> const. We can't afford to inflict such complexity on our users.
>
> The burden of defining @tail const/immutable/inout functions in addition  
> to non- at tail const/immutable/inout functions (sometimes the distinction  
> would need to be made!) is just too high. I think we need to work out  
> solutions within the existing language.

I had not thought of it this way.  I assumed you would only need to define  
a function as tail-const or const.  Certainly if a function can be const,  
you don't need a tail-const version also do you?  A ref to tail-const  
should implicitly cast to ref to const.  If you need tail-const version,  
then a const object should not be able to call this.

Immutable is different, ref to tail-immutable does not implicitly cast to  
ref immutable.  This really is a shame, I think you are right, we cannot  
do tail-const generically in this way :(  I overlooked this because arrays  
are passed to their 'member' functions generally by value and not by  
reference.  The same is not true for structs with member functions.

But we absolutely need a way to say "this is implicitly castable to it's  
tail-const version."  This is the problem I showed at the end of my  
earlier post -- you cannot implicitly convert Range into ConstRange.  It  
would be nice to have an enforceable way to allow this, so that the burden  
of proof that implicit casting works properly is not on the developer.

In addition, the way inout works would be nice to hook into this  
mechanism, so you could describe how inout applies to a tail-inout version.

Thanks for pointing this out.

-Steve


More information about the Digitalmars-d mailing list