October 21, 2015
On Wednesday, 21 October 2015 at 12:32:37 UTC, Andrei Alexandrescu wrote:
> On 10/21/2015 07:40 AM, Timon Gehr wrote:
>> On 10/21/2015 12:55 PM, Andrei Alexandrescu wrote:
>>> On 10/19/15 9:49 PM, Jonathan M Davis wrote:
>>>> On Monday, 19 October 2015 at 23:37:09 UTC, Timon Gehr wrote:
>>>>> This is the worst part:
>>>>>
>>>>> class C{
>>>>>     int[] x=[1,2,3];
>>>>> }
>>>>>
>>>>> void main(){
>>>>>     auto mut=new C;
>>>>>     auto imm=new immutable(C);
>>>>>     assert(imm.x[0]==1);
>>>>>     mut.x[0]=2;
>>>>>     assert(imm.x[0]==2);
>>>>> }
>>>>
>>>> Oooo. Ouch. Yeah, that pushes it from being a good idea to disallow this
>>>> in order to avoid bugs to a necessity to disallow it in order to avoid
>>>> breaking the type system.
>>>
>>> Please file, thanks. -- Andrei
>>>
>>
>> (I've filed it in 2013.
>> https://issues.dlang.org/show_bug.cgi?id=10376 .)
>>
>> What should be the expected behaviour?
>>
>> - Don't allow default initialization with mutable indirections in
>> aggregates.
>>
>> - Clone the mutable referenced data for each instance.
>>
>> - Have different "init" for different mutability.
>>
>> - ... ?
>
> The quickest way to stop the bleeding is to disallow the code. It's incorrect for immutable data and misleading for mutable data. (What an user might expect is that each data comes with a distinct array.)
>
> I can't believe I didn't know about this huge hole.
>
>
> Andrei

Fundamentally the problem is that literals of mutable reference types do not make sense. This is why I argued (before TDPL came out), that an explicit .dup should be required, rather than allowing the compiler to secretly add one automatically. Implicit conversion of an array literal to mutable is ridiculous IMHO.

This is just one manifestation of the problem. It could be quite difficult to come up with a rule for what should be disallowed.


October 21, 2015
On Wednesday, 21 October 2015 at 12:32:37 UTC, Andrei Alexandrescu wrote:
> The quickest way to stop the bleeding is to disallow the code. It's incorrect for immutable data and misleading for mutable data. (What an user might expect is that each data comes with a distinct array.)

It's perfectly correct for immutable data if the member variable is declared to be immutable or if it's a Rebindable which explicitly refers to immutable (in fact, SysTime would be defaulting to an immutable TimeZone for its default value if it weren't for the fact that a compiler bug is preventing it). What doesn't work is to have the member variable be declared to be mutable and then declare an instance of the object it's in to be immutable, since then you can have a mutable and immutable object referring to the same data with different levels of mutability.

- Jonathan M Davis
October 21, 2015
On 10/21/2015 02:54 PM, Don wrote:
>
> Fundamentally the problem is that literals of mutable reference types do
> not make sense.

I think considering "[x,y,z]" a 'literal' is a problem, but why is it the problem here? It is not really treated like a literal in this context. This has the same issue:

class D{ int x=0; }
class C{ auto x=new D; }

void main(){
    auto c1=new C;
    auto c2=new immutable(C);
    assert(c2.x.x==0);
    c1.x.x=1;
    assert(c2.x.x==1);
}


> This is why I argued (before TDPL came out), that an
> explicit .dup should be required, rather than allowing the compiler to
> secretly add one automatically. Implicit conversion of an array literal
> to mutable is ridiculous IMHO.

Where does the "implicit conversion to mutable" happen here?:

class C{ int x; }

void main(){
    auto c=new C;
    auto a=[c];
}
November 14, 2015
On 10/18/15 9:00 PM, David Osborne wrote:
> On Saturday, 17 October 2015 at 15:31:00 UTC, Nikolay wrote:
>> I asked on SO question about opDispatch and compile time parameters:
>> http://stackoverflow.com/questions/32998781/opdispatch-and-compile-time-parameters
>>
>> [...]
>> Is it good idea for opDispatch improvement or may there is some other
>> approach?
>
> I must have my answer not too long after you made this thread, but there
> is another approach:
> (copied from SO)
>
> You need to use the eponymous template pattern, and have an opDispatch
> function with your compile-time parameters inside an outer opDispatch
> template that takes the regular opDispatch string parameter. You can
> also have multiple inner opDispatch functions (and fields) that follow
> regular overload rules.
>
>
>      import std.stdio;
>
>      struct Foo {
>
>          public template opDispatch(string name) {
>
>              public string opDispatch() {
>                  return name;
>              }
>
>              public T opDispatch(T)() {
>                 return T.init;
>              }
>
>              public string opDispatch(T)(string s) {
>                  return name ~ ' ' ~ T.stringof ~ ' ' ~ s;
>              }
>          }
>      }
>
>      void main()
>      {
>          Foo foo;
>          writeln( foo.bar );
>          writeln( foo.baz!int );
>          writeln( foo.foo!Foo("foo") );
>      }
>
> Produces the output:
>
>      bar
>      0
>      foo Foo foo
>
> DPaste link: http://dpaste.dzfl.pl/6e5cfca8b702
>
>
> I haven't fully explored the limitations of this approach, but it does
> work for simple cases.
>

I just came across a need for this, thanks.

Is it me, or is this a bug?

struct Foo
{
   template opDispatch(string s) {
      // if you uncomment this, it compiles
      //void opDispatch() {}
      void opDispatch(T...)() {}
   }
}

void main()
{
   Foo f;
   f.blue!char(); // Error: no property 'blue' for type 'Foo'
}

-Steve
November 14, 2015
On Saturday, 14 November 2015 at 04:10:59 UTC, Steven Schveighoffer wrote:
> Is it me, or is this a bug?
>
> struct Foo
> {
>    template opDispatch(string s) {
>       // if you uncomment this, it compiles
>       //void opDispatch() {}
>       void opDispatch(T...)() {}
>    }
> }
>
> void main()
> {
>    Foo f;
>    f.blue!char(); // Error: no property 'blue' for type 'Foo'
> }
>
> -Steve

Usually you should explicitly instantiate opDispatch to see the real error message(s) that prevented opDispatch from being used, but in this case I can't find a way to do that. `f.opDispatch!("blue")!char()` is syntactically invalid, and aliasing doesn't work either: `alias t = f.opDispatch!"blue"; t!char(); // Error: need `this` for opDispatch`. I wonder what the real error is.

November 16, 2015
On 11/14/15 12:18 AM, Jakob Ovrum wrote:
> On Saturday, 14 November 2015 at 04:10:59 UTC, Steven Schveighoffer wrote:
>> Is it me, or is this a bug?
>>
>> struct Foo
>> {
>>    template opDispatch(string s) {
>>       // if you uncomment this, it compiles
>>       //void opDispatch() {}
>>       void opDispatch(T...)() {}
>>    }
>> }
>>
>> void main()
>> {
>>    Foo f;
>>    f.blue!char(); // Error: no property 'blue' for type 'Foo'
>> }
>
> Usually you should explicitly instantiate opDispatch to see the real
> error message(s) that prevented opDispatch from being used, but in this
> case I can't find a way to do that. `f.opDispatch!("blue")!char()` is
> syntactically invalid, and aliasing doesn't work either: `alias t =
> f.opDispatch!"blue"; t!char(); // Error: need `this` for opDispatch`. I
> wonder what the real error is.
>

It appears that you can't directly access the eponymous member, this doesn't work:

f.opDispatch!("blue").opDispatch!(char)();

Error: no property 'opDispatch' for type 'void'

Perhaps that fact that it *works* when you have the non-template version as the first member is the bug ;)

In any case, I have used Jack Applegame's improved version, and it works beautifully!

-Steve
1 2 3
Next ›   Last »