Re: opCast using in template struct

2012-12-08 Thread Ali Çehreli

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



Re: opCast using in template struct

2012-10-19 Thread Era Scarecrow

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.


Re: opCast using in template struct

2012-10-19 Thread Oleg

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...




opCast using in template struct

2012-10-18 Thread Oleg

Hello. How to cast template struct to itself?

struct vec(string S,T=double)
{
T[S.length] data;
auto opCast(string K,E)()
if( S.length == K.length 
 is( T : E ) )
{
vec!(K,E) ret;
foreach( i, ref m; ret.data )
m = data[i];
return ret;
}
}

unittest
{
alias vec!xyz dvec3;
alias vec!(rbg,float) fcol3;
auto a = dvec3([1,2,3]);
auto b = fcol3();
b = a; #1
assert( b.data == [1,2,3] );
}

#1 Error: cannot implicitly convert expression (a)
of type vec!(xyz) to vec!(rbg,float)


Re: opCast using in template struct

2012-10-18 Thread Oleg
Sorry. My problem more complex and my simplification is not 
correct.

I want use mixin for math operations.

mixin template vectOp( string DataName, int DataLen, T, vecType )
{
mixin( alias  ~ DataName ~  this; );

auto opBinary(string op,E)( E[DataLen] b ) 
auto opBinary(string op,E)( E[] b ) 
auto opOpBinary(string op,E)( E[] b ) 
auto opOpBinary(string op,E)( E[DataLen] b ) 

}

struct vec(string S,T=double)
{
T[S.length] data;
mixin vectOp( data, S.length, T, vec!(S,T) );
}

unittest{
   vec!xyz a;
   vec!xyz b;
   a += b;
}

and it isn't work

Error: 'a += b' is not a scalar, it is a vec!(xyz)
Error: 'a._data' is not of arithmetic type, it is a double[3LU]
Error: 'b._data' is not of arithmetic type, it is a double[3LU]


Re: opCast using in template struct

2012-10-18 Thread Simen Kjaeraas

On 2012-10-18, 17:45, Oleg wrote:


Sorry. My problem more complex and my simplification is not correct.
I want use mixin for math operations.

mixin template vectOp( string DataName, int DataLen, T, vecType )
{
 mixin( alias  ~ DataName ~  this; );

 auto opBinary(string op,E)( E[DataLen] b ) 
 auto opBinary(string op,E)( E[] b ) 
 auto opOpBinary(string op,E)( E[] b ) 
 auto opOpBinary(string op,E)( E[DataLen] b ) 

}

struct vec(string S,T=double)
{
 T[S.length] data;
 mixin vectOp( data, S.length, T, vec!(S,T) );
}

unittest{
vec!xyz a;
vec!xyz b;
a += b;
}

and it isn't work

Error: 'a += b' is not a scalar, it is a vec!(xyz)
Error: 'a._data' is not of arithmetic type, it is a double[3LU]
Error: 'b._data' is not of arithmetic type, it is a double[3LU]


I see you have opOpBinary there - should those be opOpAssign?

--
Simen


Re: opCast using in template struct

2012-10-18 Thread Era Scarecrow
On Thursday, 18 October 2012 at 18:12:49 UTC, Simen Kjaeraas 
wrote:



I see you have opOpBinary there - should those be opOpAssign?



 Probably. It's an easy mistake to make. Maybe the compiler 
should issue a warning when opAssign attempts and fails and 
opOpBinary is defined.


Re: opCast using in template struct

2012-10-18 Thread bearophile

Era Scarecrow:

It's an easy mistake to make. Maybe the compiler should issue a 
warning when opAssign attempts and fails and opOpBinary is 
defined.


If you have strong feelings about this, then add a Bugzilla entry.

There are other cases. Generally the D compiler should add some 
warnings that help against operator overloading mistakes.


Bye,
bearophile


Re: opCast using in template struct

2012-10-18 Thread Timon Gehr

On 10/18/2012 11:45 PM, bearophile wrote:

Era Scarecrow:


It's an easy mistake to make. Maybe the compiler should issue a
warning when opAssign attempts and fails and opOpBinary is defined.




This would have to be implemented very carefully. There are enough
hard to reproduce symbol resolution bugs already. It does not get
better by introducing hidden and unnecessary lookups.


If you have strong feelings about this, then add a Bugzilla entry.

There are other cases. Generally the D compiler should add some warnings
that help against operator overloading mistakes.

Bye,
bearophile


I don't think that operator overloading gives rise to distinct mistakes.
For example, better error messages that just specify the expected name,
as in other cases of undefined identifiers, would already fix this.


Re: opCast using in template struct

2012-10-18 Thread Era Scarecrow

On Thursday, 18 October 2012 at 22:07:55 UTC, Timon Gehr wrote:

On 10/18/2012 11:45 PM, bearophile wrote:
There are other cases. Generally the D compiler should add 
some warnings that help against operator overloading mistakes.


I don't think that operator overloading gives rise to distinct 
mistakes. For example, better error messages that just specify 
the expected name, as in other cases of undefined identifiers, 
would already fix this.


 Inside a function a badly named identifier becomes obvious since 
it outright tells you. But with regards to opOpAssign and other 
operator overloading I see the error message and I see the call 
but I don't see why it fails. Then I'll try adjusting the 
signature on my function, not realizing it never sees it in the 
first place due to misspelling.


 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...


Re: opCast using in template struct

2012-10-18 Thread bearophile

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


Re: opCast using in template struct

2012-10-18 Thread Timon Gehr

On 10/19/2012 01:05 AM, Era Scarecrow wrote:

On Thursday, 18 October 2012 at 22:07:55 UTC, Timon Gehr wrote:

On 10/18/2012 11:45 PM, bearophile wrote:

There are other cases. Generally the D compiler should add some
warnings that help against operator overloading mistakes.


I don't think that operator overloading gives rise to distinct
mistakes. For example, better error messages that just specify the
expected name, as in other cases of undefined identifiers, would
already fix this.


  Inside a function a badly named identifier becomes obvious since it
outright tells you. But with regards to opOpAssign and other operator
overloading I see the error message and I see the call but I don't see
why it fails.


My suggestion was something like:

error: expression 'e' of type 'S' is not of arithmetic type and it does 
not define opOpAssign!+.


The compiler should indicate exactly why it fails. If this is not
enough, then the programmer certainly deserves the headache.


Then I'll try adjusting the signature on my function, not
realizing it never sees it in the first place due to misspelling.



If the issue _is_ with the signature, then the compiler should tell you.
That is the (secondary) job of the compiler.


  Maybe.. A general warning when something starts with 'op(Op)?[A-Z]'


'op[A-Z]'


but doesn't actually qualify as any of the override-able operators? That
seems sensible...


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


Re: opCast using in template struct

2012-10-18 Thread Timon Gehr

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?


Re: opCast using in template struct

2012-10-18 Thread bearophile

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


Re: opCast using in template struct

2012-10-18 Thread Timon Gehr

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