October 23, 2015
On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote:
> On 10/22/15 1:09 AM, deadalnix wrote:
>> The elephant in the room: make the template parameter's type qualifier
>> transitive with the collection's qualifier.
>
> Could you please give more detail on this? Thanks! -- Andrei

Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect.

Collection!T and Collection!const(T) are 2 completely different types. There is a good reason for this : static if (is(T == const)) { ... } . As a result thing like :

void foo(T)(const Collection!const(T) c) {}
void main() {
  Collection!T c;
  foo(c); // Error, GTFO !
}

With the different qualifiers and implicit conversion, thing become quite tricky. You can simulate them partially with a set of carefully crafted alias this (but not having multiple alias this doesn't make things any simpler) but there is the monster of mutually recursive template instanciation that is lurking.

As far as i know, jmdavis had some good work done on this, but it was far from perfect.

October 23, 2015
On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote:

> Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect.
>
> Collection!T and Collection!const(T) are 2 completely different types. There is a good reason for this : static if (is(T == const)) { ... } . As a result thing like :
>
> void foo(T)(const Collection!const(T) c) {}
> void main() {
>   Collection!T c;
>   foo(c); // Error, GTFO !
> }
>
> With the different qualifiers and implicit conversion, thing become quite tricky. You can simulate them partially with a set of carefully crafted alias this (but not having multiple alias this doesn't make things any simpler) but there is the monster of mutually recursive template instanciation that is lurking.
>
> As far as i know, jmdavis had some good work done on this, but it was far from perfect.

Why not just pass a range to foo?


October 23, 2015
On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote:
> On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote:
>> [...]
>
> Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect.
>
> [...]

Its not just type qualifiers. Containers of derived types have the same problem.  This is also a problem in C++.

October 23, 2015
On Friday, 23 October 2015 at 23:21:31 UTC, bigsandwich wrote:
> On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote:
>> On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote:
>>> [...]
>>
>> Sure. We have a problem when it come to collection in the fact that type qualifier do not turtle down as one would expect.
>>
>> [...]
>
> Its not just type qualifiers. Containers of derived types have the same problem.  This is also a problem in C++.

Thinking deeper about this, it _should_ be the case that deadalnix's example doesn't compile.

struct Container(T) {
    static if(is(T == const))
         int changesLayout; // etc...
    int stuff;
}

    Bit

October 24, 2015
On 10/24/2015 01:36 AM, bitwise wrote:
> On Friday, 23 October 2015 at 23:21:31 UTC, bigsandwich wrote:
>> On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote:
>>> On Friday, 23 October 2015 at 11:03:37 UTC, Andrei Alexandrescu wrote:
>>>> [...]
>>>
>>> Sure. We have a problem when it come to collection in the fact that
>>> type qualifier do not turtle down as one would expect.
>>>
>>> [...]
>>
>> Its not just type qualifiers. Containers of derived types have the
>> same problem.  This is also a problem in C++.
>
> Thinking deeper about this, it _should_ be the case that deadalnix's
> example doesn't compile.
>
> struct Container(T) {
>      static if(is(T == const))
>           int changesLayout; // etc...
>      int stuff;
> }
>
>      Bit
>

One could introduce a way to indicate that const-conversions should be performed for instantiations of a given templated aggregate with identical layouts.
October 24, 2015
On 2015-10-21 13:05, Andrei Alexandrescu wrote:

> 1. Functional containers.
>
> These are immutable; once created, neither their topology nor their
> elements may be observably changed. Manipulating a container entails
> creating an entire new container, often based on an existing container
> (e.g. append takes a container and an element and creates a whole new
> container).
>
> Internally, functional containers take advantage of common substructure
> and immutability to share actual data. The classic resource for defining
> and implementing functional containers is
> http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504.

Can these be implemented by the user just declaring a regular container as immutable? The implement will recognize if it's declared as immutable and adapt.

-- 
/Jacob Carlborg
October 24, 2015
On Saturday, 24 October 2015 at 09:22:37 UTC, Jacob Carlborg wrote:
> Can these be implemented by the user just declaring a regular container as immutable? The implement will recognize if it's declared as immutable and adapt.

How can a type know it's qualifier?

struct Container(T)
{
   //.... access qualifier somehow do stuff with it
}

alias SM  = Container!int;
alias SIM = immutable Container!int;

It was my understanding that S!int only gets instantiated one time here? Or does the compiler instantiate (immutable S!int) and (S!int)? Or were you thinking of something else?


October 24, 2015
On 10/24/2015 11:22 AM, Jacob Carlborg wrote:
> On 2015-10-21 13:05, Andrei Alexandrescu wrote:
>
>> 1. Functional containers.
>>
>> These are immutable; once created, neither their topology nor their
>> elements may be observably changed. Manipulating a container entails
>> creating an entire new container, often based on an existing container
>> (e.g. append takes a container and an element and creates a whole new
>> container).
>>
>> Internally, functional containers take advantage of common substructure
>> and immutability to share actual data. The classic resource for defining
>> and implementing functional containers is
>> http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504.
>>
>
> Can these be implemented by the user just declaring a regular container
> as immutable? The implement will recognize if it's declared as immutable
> and adapt.
>

Even if this was possible, it would not be a very good idea. Persistent data structures have use cases that would be hindered by required transitive immutability.
October 24, 2015
On 10/24/15 3:19 PM, Timon Gehr wrote:
> Even if this was possible, it would not be a very good idea. Persistent
> data structures have use cases that would be hindered by required
> transitive immutability.

This part I don't quite get. Are there any languages that offer containers with immutable topology but mutable slots, and call them persistent data structures? -- Andrei
October 24, 2015
On Friday, 23 October 2015 at 17:44:55 UTC, deadalnix wrote:
> Collection!T and Collection!const(T) are 2 completely different types.

Isn't this also required anyway because of covariance vs. contravariance considerations?

 — David