October 18, 2012
On 10/19/2012 01:23 AM, bearophile wrote:
> Era Scarecrow:
>
>>  Maybe.. A general warning when something starts with 'op(Op)?[A-Z]'
>> but doesn't actually qualify as any of the override-able operators?
>> That seems sensible...
>
> Regarding operator overloading there are several situations worth
> warning the programmer of. The D compilers should be improved on this.
>
> Bye,
> bearophile

What situations?
October 19, 2012
Timon Gehr:

> What situations?

This thread has already shown two possible cases worth discussing about.

This report shows two more cases:
http://d.puremagic.com/issues/show_bug.cgi?id=8844

Two more cases:

Foo opBinary(string op="/\")(Foo f) {}
Foo opBinary(string op)(Foo f) if (op == "@") {}

And several other situations.

Bye,
bearophile
October 19, 2012
On 10/19/2012 02:12 AM, bearophile wrote:
> Timon Gehr:
>
>> What situations?
>
> This thread has already shown two possible cases worth discussing about.
>
> This report shows two more cases:
> http://d.puremagic.com/issues/show_bug.cgi?id=8844
>

How is that bug-prone? Are there keyboards where : and = are close?

> Two more cases:
>
> Foo opBinary(string op="/\")(Foo f) {}

That is not even going to pass the lexing stage.

> Foo opBinary(string op)(Foo f) if (op == "@") {}
>

What is the issue?

> And several other situations.
>
> Bye,
> bearophile

October 19, 2012
On Thursday, 18 October 2012 at 23:51:44 UTC, Timon Gehr wrote:
>If the issue _is_ with the signature, then the compiler should tell you. That is the (secondary) job of the compiler.

 But not everything is parsed/compiled if it doesn't match the constraints, especially template functions. Sometimes I wish I had more information of what signatures it generated, what it compared against, and why each of them were disqualified; But that's regarding more complex stuff.


> That is a lot better, but what if the typo is within the first 3 characters? :o)

 If the beginning doesn't match 'op(Op)?[A-Z]', then you can't safely guess it was ever intended to override operators.  If it has the keyword override then you know in a class it's polymorphic, however in a struct.... Hmmm...  i don't know.

 Maybe a small suite list of tests that go through a few dozen templates and tells you what a struct qualifies for, like ranges, random access, forward/reverse, infinite. Etc. Might be more informational but if you expect you struct to do something and it doesn't qualify then you have a better idea at least of what is wrong.
October 19, 2012
Problem solved partially.

http://dpaste.dzfl.pl/e7871a01

in structs I use fix length arrays declarations, and alias its to structs, but not allowed casting to fix length arrays.
I want check array length in compile time

    auto opBinary(string op,E)( E[DLen] b ) // fix length array
        if( ( op == "+" || op == "-" ) && is( E : T ) )
    {
        // without this checking in runtime
        //if( DLen != b.length )
        //    throw new Exception("bad length");
        auto res = VecT(this);
        foreach( i, ref m; mixin( "res." ~ DName ) )
            mixin( "m " ~ op ~ "= b[i];" );
        return res;
    }

if I write E[DLen] I have errors like this

 Error: template opop.vec!("xyz").vec.arrayMath!("data",3LU,double,vec!("xyz")).opAssign does not match any function template declaration

 Error: template opop.vec!("xyz").vec.arrayMath!("data",3LU,double,vec!("xyz")).opAssign(E) if (is(E : T)) cannot deduce template function from argument types !()(int[])

but declaration like this allowed
int[4] f = [1,2,3,4];

also checked in compile time assigning like this
int[4] f;
int[5] g;
g = f; // -> Error: mismatched array lengths, 5 and 4

I think in my situation checking in compile time must be possibly, because all of template params known in compile time, but I unknown how to use it...

December 08, 2012
On 10/19/2012 06:38 AM, Oleg wrote:
> Problem solved partially.
>
> http://dpaste.dzfl.pl/e7871a01
>
> in structs I use fix length arrays declarations, and alias its to
> structs, but not allowed casting to fix length arrays.
> I want check array length in compile time
>
> auto opBinary(string op,E)( E[DLen] b ) // fix length array

E[DLen] is good above. You can also consider taking by 'const ref' if DLen is too large. Otherwise, being value-types, fixed-length arrays normally get copied to functions.

> if( ( op == "+" || op == "-" ) && is( E : T ) )
> {
> // without this checking in runtime
> //if( DLen != b.length )
> // throw new Exception("bad length");

Yes, that is not needed anymore because now it is known that b.length is always DLen.

> auto res = VecT(this);
> foreach( i, ref m; mixin( "res." ~ DName ) )
> mixin( "m " ~ op ~ "= b[i];" );
> return res;
> }
>
> if I write E[DLen] I have errors like this
>
> Error: template
> opop.vec!("xyz").vec.arrayMath!("data",3LU,double,vec!("xyz")).opAssign
> does not match any function template declaration
>
> Error: template
> opop.vec!("xyz").vec.arrayMath!("data",3LU,double,vec!("xyz")).opAssign(E)
> if (is(E : T)) cannot deduce template function from argument types
> !()(int[])

The problem is that array literals are slices, not fixed-length arrays.

    pragma(msg, typeof([1,2,3]));

prints

int[]

> but declaration like this allowed
> int[4] f = [1,2,3,4];

Because in that case the type of f is explicitly int[4]. The following would not be:

auto f = [1,2,3];

The type of f is int[].

Of course it is possible to support both arrays and slices, and avoid the check by something like isStaticArray, but your callers will have to be aware of the fact that array literals are slices.

Ali

1 2
Next ›   Last »