September 06, 2022

On Tuesday, 6 September 2022 at 11:09:26 UTC, Loara wrote:

>

On Tuesday, 6 September 2022 at 10:06:59 UTC, Quirin Schroll wrote:

>
  • Aforementioned const(int*) becoming const(int)*. That does not happen with custom struct S(T) automatically even in cases where it is provably correct, and there is no way to tell the D compiler that copies of const(S!int) are better understood to be S!(const int).

Consider

struct S(T){
  T val;
  int idx;

  void inc(){
    idx++;
  }
}

then s.inc() is valid if s id S!(const int) but not if s is const S!int!

Of course. That’s e.g. what a reference counted pointer would do.

>

Again consider

struct S(T){
   int dat;
   T func(T dat){ ... }
}

in this example conversion of S!(const int) to const S!int has much less sense. If you want to perform a such conversion then you should instead introduce a "cloning" method:

This one isn’t even vaguely a container of T. You could argue about int*, and the case for int[] is obvious.

I’m not entirely sure what you want to tell me. In the cases of containers, it’s probably even possible to a large degree to use introspection to provide a wide-ranging clone. The relevant part is that when you clone, you have to be explicit.

There’s tension between stuff being handy when using known types and known functions, and stuff being simple using templates’ type arguments and function templates.

September 07, 2022

On Tuesday, 6 September 2022 at 17:45:50 UTC, Nick Treleaven wrote:

>

On Tuesday, 6 September 2022 at 10:06:59 UTC, Quirin Schroll wrote:

>
  • Aforementioned const(int*) becoming const(int)*. That does not happen with custom struct S(T) automatically even in cases where it is provably correct, and there is no way to tell the D compiler that copies of const(S!int) are better understood to be S!(const int).

There is at least a library pattern:
https://dlang.org/blog/2020/06/25/a-pattern-for-head-mutable-structures/

I really wish that had gone somewhere. There's not a lot of code to it, it's almost all library code that the user doesn't see, and it would provide a solution while we wait for the promised compiler support for the same thing (which I don't think would be very different - you'll need to specify the behavior for complex cases anyway). Also, it's not worth a whole lot as a library if Phobos doesn't implement it.

--
Simen

September 07, 2022

On Tuesday, 6 September 2022 at 17:48:53 UTC, Quirin Schroll wrote:

>

This one isn’t even vaguely a container of T.

Exactly, what you say is valid only for containers not for generic templated objects. It's better to provide a custom method that apply the needed conversion:

struct myContainer(T){
  ...
  const(myContainer!(Unconst!T)) shareConst() const{
    //do stuff
  }
}
>

I’m not entirely sure what you want to tell me. In the cases of containers, it’s probably even possible to a large degree to use introspection to provide a wide-ranging clone. The relevant part is that when you clone, you have to be explicit.

I don't think that could be possible to implement such feature without heavy drawbacks, it's smarter to implement custom conversion methods for each templated object since "cloning an object" may assume different meaning depending of its type. For example in this project cloning an object means "create a new object that doesn't share any indirection with the original one", however this condition is often too restrictive for containers since you don't want to clone each stored object.

An unique solution that works for every object doesn't exists, it's better that each programmer implements the preferred strategy in his code.

1 2 3
Next ›   Last »