December 10, 2011
On 12/10/2011 11:18 AM, Mehrdad wrote:
> ... and another...
>
> struct S(T, int N)
> { public auto opBinary(string op)(in S!(T, N) other) const { return
> this; } }
> void main() { S!(int, 1) m; m = m * m; }
>
> Error: 'm' is not of arithmetic type, it is a Matrix!(int,1)
> Error: 'm' is not of arithmetic type, it is a Matrix!(int,1)

It is unrelated to const, this gives the same error.
struct S(T, int N)
{ public auto opBinary(string op)(S!(T, N) other) { return this; } }
void main() { S!(int, 1) m; m = m * m; }

And this works:

struct S(T, int N)
{ public auto opBinary(string op)(in S other) const { return this; } }
void main() { S!(int, 1) m; m = m * m; }

You have to make sure that the signature of your template actually compiles. Maybe the compiler should emit a diagnostic for that case.


If you blame all your compile errors on const, I can understand why you think its design is broken.
December 10, 2011
On 12/10/2011 2:00 AM, Timon Gehr wrote:
> On 12/10/2011 10:37 AM, Mehrdad wrote:
>> I just thought I'd give D another try, after having given up on it for a
>> while.
>>
>> Lo and behold... the same old kind of problem from a year ago is still
>> here. :(
>>
>> Simple stuff like this:
>>
>> import std.algorithm;
>> void main() {
>> const arr = [1, 2, 3];
>> reduce!"a*b"(arr); // You'd think it'd work...
>> }
>>
>> Results in ridiculously annoying errors like:
>> // algorithm.d(728): Error: can only initialize const member
>> _field_field_0 inside constructor
>>
>> I **HIGHLY** suggest that priority be given to simple problems like
>> these, instead of OMG-so-cool-libraries.
>
> It is a *library bug*. Just have a look at the source code.
Sure.
Did I say something else?

>> It really doesn't matter if
>> there is an uber-awesome collections/CURL/whatever library out there,
>> when problems like these exist. If a 2-line piece of code needs a
>> workaround, then (IMO) people simply won't care about anything else
>> that's more complicated.
>>
>> I'll post more as I find them. (I'd found plenty a few months ago, now I
>> just need to find them again.)
>> Too lazy/busy studying to post as a bug. And it feels a bit better when
>> I add the complaint. :P
>>
>> (Sorry for being so critical but at least I tried to make it
>> constructive...)
>
> Just slice the const array to get a range. The specialization for ranges does not have the bug.
Thanks for the workaround, but it's still a workaround, not a fix. :P
December 10, 2011
On 12/10/2011 11:34 AM, Mehrdad wrote:
> ... and another...
>
> struct Matrix(T, size_t N = 1)
> { public auto mul(Matrix!(T, N) other) const { return this; } }
>
> void main()
> {
> Matrix!(int, 2) m;
> m.mul(m);
> }
>
> annoy.d(7): Error: function annoy.Matrix!(int,2).Matrix.mul
> (Matrix!(int,N) other) const is not callable using argument types
> (Matrix!(int,2))
> annoy.d(7): Error: cannot implicitly convert expression (m) of type
> Matrix!(int,2) to Matrix!(int,N)

Again, unrelated to const. This works:

struct Matrix(T, size_t N = 1)
{ public auto mul(Matrix other) const { return this; } }

void main()
{
    Matrix!(int, 2) m;
    m.mul(m);
}

But it seems to be a bug indeed, because this compiles:

struct Matrix(T, size_t N = 1)
{ public auto mul(Matrix!(T, 2) other) const { return this; } }

void main()
{
    Matrix!(int, 2) m;
    m.mul(m);
}
December 10, 2011
On 12/10/2011 2:46 AM, Timon Gehr wrote:
> On 12/10/2011 11:18 AM, Mehrdad wrote:
>> ... and another...
>>
>> struct S(T, int N)
>> { public auto opBinary(string op)(in S!(T, N) other) const { return
>> this; } }
>> void main() { S!(int, 1) m; m = m * m; }
>>
>> Error: 'm' is not of arithmetic type, it is a Matrix!(int,1)
>> Error: 'm' is not of arithmetic type, it is a Matrix!(int,1)
>
> It is unrelated to const, this gives the same error.
> struct S(T, int N)
> { public auto opBinary(string op)(S!(T, N) other) { return this; } }
> void main() { S!(int, 1) m; m = m * m; }
Yeah, I've complained about const before, but I never said this one was related. :P I just had the word 'const' in there because it was in my original code and I forgot to take it out.

> And this works:
>
> struct S(T, int N)
> { public auto opBinary(string op)(in S other) const { return this; } }
> void main() { S!(int, 1) m; m = m * m; }
>
> You have to make sure that the signature of your template actually compiles. Maybe the compiler should emit a diagnostic for that case.
Sure, but what's wrong with my version that makes it not compile?

> If you blame all your compile errors on const, I can understand why you think its design is broken.

Not _all_ of them (e.g. I figured this one wasn't one of them), but yes, a significant fraction of them that I've seen, only a few of which I've been in the mood to post. :)
So yeah, that's why I've come to the conclusion that it's broken.
December 10, 2011
On 12/10/2011 11:45 AM, bearophile wrote:
> Timon Gehr:
>
>> Just slice the const array to get a range. The specialization for ranges
>> does not have the bug.
>>
>> import std.algorithm;
>> void main() {
>>       const arr = [1, 2, 3];
>>       reduce!"a*b"(arr[]);   // It works.
>> }
>
> Wasn't arr a range already?
>
> Bye,
> bearophile

No, popFront is mutating and const(int[]) cannot be mutated.
December 10, 2011
Oh right, I see why you assumed I blamed it on const -- it's in the title of the post.

Nah, only the beginning was about const. The rest was the issues I saw when working on the same library, so I posted them here. Sorry for keeping the (now-misleading) title.
December 10, 2011
On 12/10/2011 2:34 AM, Mehrdad wrote:
> ... and another...
>
> struct Matrix(T, size_t N = 1)
> { public auto mul(Matrix!(T, N) other) const { return this; } }


In general, to refer to the current template being expanded from inside of it, just give its name, as in:

Matrix!(T,N) => Matrix
December 10, 2011
On 12/10/2011 3:01 AM, Walter Bright wrote:
> On 12/10/2011 2:34 AM, Mehrdad wrote:
>> ... and another...
>>
>> struct Matrix(T, size_t N = 1)
>> { public auto mul(Matrix!(T, N) other) const { return this; } }
>
>
> In general, to refer to the current template being expanded from inside of it, just give its name, as in:
>
> Matrix!(T,N) => Matrix
That's not the issue.

If you say 'int' instead of size_t, it works fine.
December 10, 2011
Timon Gehr:

> No, popFront is mutating and const(int[]) cannot be mutated.

So, is it impossible by design to iterate immutable collections?

Bye,
bearophile
December 10, 2011
On 12/10/2011 3:08 AM, bearophile wrote:
> Timon Gehr:
>
>> No, popFront is mutating and const(int[]) cannot be mutated.
> So, is it impossible by design to iterate immutable collections?
>
> Bye,
> bearophile

I believe the answer is yes (although Timon would probably know better).

That's one reason I believe const is broken...