September 20, 2003
> > I can tell you that ++e is definitely not semantically equivalent to e
+=
> 1,
> > because many things can be incremented but not necessarily by an
arbitrary
> > integer amount (not to mention += negative number).
>
> In those cases, an assert(i == 1) in the addass(int i) operator should
> handle it.
>

I don't want run-time check when a compile-time could have detect the error easily...

I would prefer that if would be possible to define opPlusPlus and/or opLessLess if addass is not defined...

For operator naming, I would like a syntax similar to the one used in C++ (with some exceptions for cmp for example where operator cmp would be used).

For that latter operator, I would say that I would like to have
the possibility to be able to define one or two operator among
<, <¸=, > and >= and have the compiler generate the others
so that the compiler could generate more efficient code in
some cases (one comparison instead of 2) except if you can
tell me that the compiler is smart enough to do the optimisation
itself...



September 20, 2003
Walter wrote:
> Some long awaited features.
> 
> http://www.digitalmars.com/d/changelog.html
> 

is this the "correct" responce from D ?

class A {
	int tag;
	this( int tag0 ) { tag = tag0; }
	void dump() { printf("A:%d\n", tag); }
}
class C : A {
	int tagw;
	this( int tag0 ) { super( tag0+100);tagw = tag0; }
	void dump() { printf("C:%d\n", tagw); }
}

class B {
	 this() { }
	 A add( B b ) { return new A(3); }
	 A add( D b ) { return new A(2); }
}

class D : B {
	 this() { }
	 C add( B b ) { return new C(4); }
	 C add( D b ) { return new C(5); }
}


int main( char[][] argv ) {
	D d = new D();
	B b = d;
	A a;
	a = b + b;
	a.dump();
	a = b + d;
	a.dump();
	a = d + d;
	a.dump();
	a = d + b;
	a.dump();
	
	return 1;
}
---- output ----
C:4
C:5
C:5
C:4

------------------ test 2 -----------------

class A {
	int tag;
	this( int tag0 ) { tag = tag0; }
	void dump() { printf("A:%d\n", tag); }
}
class C : A {
	int tagw;
	this( int tag0 ) { super( tag0+100);tagw = tag0; }
	void dump() { printf("C:%d\n", tagw); }
}

class B {
	 this() { }
	 A add( B b ) { return new A(3); }
//	 A add( D b ) { return new A(2); }
}

class D : B {
	 this() { }
	 C add( B b ) { return new C(4); }
	 C add( D b ) { return new C(5); }
}


int main( char[][] argv ) {
	D d = new D();
	B b = d;
	A a;
	a = b + b;
	a.dump();
	a = b + d;
	a.dump();
	a = d + d;
	a.dump();
	a = d + b;
	a.dump();
	
	return 1;
}
-------------- op -----------------
C:4
C:4
C:5
C:4
---------------- test 3 --------------
class B {
	 this() { }
	 A add( B b ) { return new A(3); }
//	 A add( D b ) { return new A(2); }
}

class D : B {
	 this() { }
//	 C add( B b ) { return new C(4); }
	 C add( D b ) { return new C(5); }
}

will not compile all +'s :
> opvl.d(36): function add (D b) does not match argument types (B )
that is the line a = d + b;
----------------- test 3a ---------------

class A {
	int tag;
	this( int tag0 ) { tag = tag0; }
	void dump() { printf("A:%d\n", tag); }
}
class C : A {
	int tagw;
	this( int tag0 ) { super( tag0+100);tagw = tag0; }
	void dump() { printf("C:%d\n", tagw); }
}

class B {
	 this() { }
	 A add( B b ) { return new A(3); }
//	 A add( D b ) { return new A(2); }
}

class D : B {
	 this() { }
//	 C add( B b ) { return new C(4); }
	 C add( D b ) { return new C(5); }
}


int main( char[][] argv ) {
	D d = new D();
	B b = d;
	A a;
	a = b + b;
	a.dump();
	a = b + d;
	a.dump();
	a = d + d;
	a.dump();
//	a = d + b;
//	a.dump();
	
	return 1;
}
-------op----
> A:3
> A:3
> C:5




September 20, 2003
I'm equally happy with __add__ and operator add(). Just not opAdd

In fact I think I like operator add() more.

However, it begs the question why we just don't have operator +() ?

"Walter" <walter@digitalmars.com> wrote in message news:bkgdgr$1vnq$1@digitaldaemon.com...
>
> "Julio César Carrascal Urquijo" <adnoctum@phreaker.net> wrote in message news:bkgc6t$1rdg$1@digitaldaemon.com...
> > They could be the short names that we have right now:
> >
> > operator cmp()
> > operaror add()
> > operator addass()
> > ...
> >
> > The thing is that they should not collide with regular user-defined
> methods
> > (Hence the name mangling). The new "operator" keyword should stand out suficiently and probably will be easier for syntax highlighting
algorithms
> > than using regular methods with special names.
>
> Hmm. I do like that better than __xxx__ !
>
>


September 20, 2003
Also, all this merry nomenclatural banter masks the deeper issue of concern that operators are member functions. :(


"Matthew Wilson" <matthew@stlsoft.org> wrote in message news:bkgh89$2d4f$1@digitaldaemon.com...
> I'm equally happy with __add__ and operator add(). Just not opAdd
>
> In fact I think I like operator add() more.
>
> However, it begs the question why we just don't have operator +() ?
>
> "Walter" <walter@digitalmars.com> wrote in message news:bkgdgr$1vnq$1@digitaldaemon.com...
> >
> > "Julio César Carrascal Urquijo" <adnoctum@phreaker.net> wrote in message news:bkgc6t$1rdg$1@digitaldaemon.com...
> > > They could be the short names that we have right now:
> > >
> > > operator cmp()
> > > operaror add()
> > > operator addass()
> > > ...
> > >
> > > The thing is that they should not collide with regular user-defined
> > methods
> > > (Hence the name mangling). The new "operator" keyword should stand out suficiently and probably will be easier for syntax highlighting
> algorithms
> > > than using regular methods with special names.
> >
> > Hmm. I do like that better than __xxx__ !
> >
> >
>
>


September 20, 2003
Walter wrote:
> Some long awaited features.
> 
> http://www.digitalmars.com/d/changelog.html
> 
> 
> 

why is opIndex( T idx ) only?

Basic uses () for array indexing .... you can fake it all with
opCall ....
and by returning a T* allow read/write
as in this simple 2d array class ...

not sure if opIndex is redundant or if it should allow multipul indexors

import c.stdio;

class B {
	int[] data;
	int lw;
	 this( int xw, int yw ) { lw = xw; data=new int[xw*yw]; }
	 int[] opCall( int y ) { return this[y]; }
	 int *  opCall( int x, int y ) { return &data[(y*lw)+x]; }
	 int[] opIndex( int y ) { return data[(y*lw)..((y*lw)+lw)]; }
	void dump() {
		printf( "data [" ); foreach( int v; data ) { printf( "%d, ", v ); }
		printf( "]\n" );
	}
}

int main( char[][] argv ) {
	B b = new B( 2, 2 );
	int[] ar = b[0];
	printf("ar.length:%d\n", ar.length);
	ar[0] = 1; ar[1] = 2;
	*(b(1,1)) =3;
	*(b(0,1)) =-4;
	b.dump();
	
	return 1;
}

--------- however the old slice append overrunn bug/feature occurs ---
int main( char[][] argv ) {
	B b = new B( 2, 2 );
	int[] ar = b[0];
	printf("ar.length:%d\n", ar.length);
	ar[0] = 1; ar[1] = 2;
	*(b(1,1)) =3;
	*(b(0,1)) =-4;
	b.dump();
	ar ~= 100;
	b.dump();
	
	return 1;
}

outputs
> ar.length:2
> data [1, 2, -4, 3, ]
> data [1, 2, 100, 3, ]


September 20, 2003
Bug:

What was

    foreach(Value value; key.propget_Values())

is now

    foreach(Value value; key.Values)

Looks nice. Doesn't compile. :(

    "win32_reg_test.d(15): foreach: ValueSequence () is not an aggregate
type"

It works ok if I change the code to

    ValueSequence values = key.Values;

    foreach(Value value; values)

but that spoils the fun a little. :)

This is not a great emergency, since the above workaround is eminently reasonable. However, it'd be good if it could be fixed in 0.74



"Walter" <walter@digitalmars.com> wrote in message news:bked8d$2pe5$1@digitaldaemon.com...
> Some long awaited features.
>
> http://www.digitalmars.com/d/changelog.html
>
>
>


September 20, 2003
"Walter" <walter@digitalmars.com> wrote in message news:bkfejj$27cl$2@digitaldaemon.com...
> > I can tell you that ++e is definitely not semantically equivalent to e
+=
> 1,
> > because many things can be incremented but not necessarily by an
arbitrary
> > integer amount (not to mention += negative number).
>
> In those cases, an assert(i == 1) in the addass(int i) operator should
> handle it.

So can you ++ floats then?  ;)

What if I want my class to be able to add, but not ++?  For instance if there is no well defined "next" to go to, but you can "add" some arbitrary amount.  For instance, maybe a set.  Yeah this example is probably an abuse of operator overloading (you'd probably overload ~=).  You can add items to a set but can't increment a set.

Sean


September 20, 2003
Walter wrote:
> Some long awaited features.
> 
> http://www.digitalmars.com/d/changelog.html
> 

is it just me or is int opSlice() pointless ?
 I've written a copy on extend slice class but howcan I write the overloaded operator to allow
a[]=b[]; to work as it does for arrays
there is no operator =/assign

this simple addition would allow opIndex to return a "ref" class
(although does require operator toType/cast to allow
template lists(T) {
	class ref {
		T* ptr;
		this( T* ptr0 ) { ptr = ptr0; }
		operator T { return *ptr; }
		operator = ( T v ) { *ptr = v; }
	}
	class vector {
		T[] data;
		this( int len ) { data = new T[len]; }
		ref opIndex( int i ) { return new ref( &t[i] ); }
	}
	
}
instance lists(int).vector ar =
	new instance lists(int).vector(3);
int a = ar[2];
ar[1] = 33;

as overloading
int * opCall( int i ) { return &t[i]; }
does not allow detection of writes


September 20, 2003
Mike Wynn wrote:
> Walter wrote:
> 
>> Some long awaited features.
>>
>> http://www.digitalmars.com/d/changelog.html
>>
> 
> is it just me or is int opSlice() pointless ?
>  I've written a copy on extend slice class but howcan I write the overloaded operator to allow
> a[]=b[]; to work as it does for arrays
> there is no operator =/assign
> 
> this simple addition would allow opIndex to return a "ref" class
> (although does require operator toType/cast to allow
> template lists(T) {
>     class ref {
>         T* ptr;
>         this( T* ptr0 ) { ptr = ptr0; }
>         operator T { return *ptr; }
>         operator = ( T v ) { *ptr = v; }
>     }
>     class vector {
>         T[] data;
>         this( int len ) { data = new T[len]; }
>         ref opIndex( int i ) { return new ref( &t[i] ); }
>     }
>     }
> instance lists(int).vector ar =
>     new instance lists(int).vector(3);
> int a = ar[2];
> ar[1] = 33;
> 
> as overloading
> int * opCall( int i ) { return &t[i]; }
> does not allow detection of writes
> 

forgot .. this was as far as my experiment went ...


import c.stdio;
template Coe( T ) {
	class Block {
		T[] slice;
		bit copyneeded;
		this( T[] from ) { slice = from; copyneeded = true; }
		T opCall( int i ) { return slice[i]; }
		T opIndex( int i ) { return slice[i]; }
		T opIndex( int i, T v ) { return (slice[i] = v); }
		void catass( T v ) {
			if ( copyneeded ) {
				slice = slice.dup;
				copyneeded = false;
			}
			slice ~= v;
		}
		int length() { return slice.length; }
		int apply( int delegate( inout T ) func ){
			foreach( inout T t; slice ) {
				int i;
				i = func( t );
				if ( i ) { return i; }
			}
			return 0;
		}
	}
}
class B {
	alias instance Coe( int ).Block BA;
	int[] data;
	int lw;
	 this( int xw, int yw ) { lw = xw; data=new int[xw*yw]; }
	 BA opCall( int y ) { return this[y]; }
//	 int   opCall( int x, int y ) { return this[y][x]; }
	 int *  opCall( int x, int y ) { return &data[(y*lw)+x]; }
	 BA opIndex( int y ) { return new BA(data[(y*lw)..((y*lw)+lw)]); }
	void dump() {
		printf( "data [" ); foreach( int v; data ) { printf( "%d, ", v ); }
		printf( "]\n" );
	}
}



int main( char[][] argv ) {
	B b = new B( 2, 2 );
	B.BA ar = b[0];
	printf("ar.length:%d\n", ar.length);
	ar[0] = 1; ar[1] = 2;
	*(b(1,1)) =3;
	*(b(0,1)) =-4;
	b.dump();
	ar ~= 100;
	b.dump();
	printf( "ar[" );
	foreach( int i; ar ) { printf( "%d, ", i ); }
	printf( "]\n" );
	
	return 1;
}

September 20, 2003
"Philippe Mori" <philippe_mori@hotmail.com> wrote in message news:bkgg88$28ta$1@digitaldaemon.com...
> > > I can tell you that ++e is definitely not semantically equivalent to e
> +=
> > 1,
> > > because many things can be incremented but not necessarily by an
> arbitrary
> > > integer amount (not to mention += negative number).
> >
> > In those cases, an assert(i == 1) in the addass(int i) operator should
> > handle it.
> >
>
> I don't want run-time check when a compile-time could have detect the error easily...

Good reason!

> I would prefer that if would be possible to define opPlusPlus and/or opLessLess if addass is not defined...

Even if it is defined!

> For operator naming, I would like a syntax similar to the one used in C++ (with some exceptions for cmp for example where operator cmp would be used).

I don't mind C++ syntax for operators.  Though heck you could just override @+ or --@ or @[].  Maybe `+.  Maybe this would make everybody else happy, some standard prefix for operators that is in fact a hopefully easy to type symbol that is otherwise unused in D.  You could maybe force people to call an overloaded operator by also using the symbol, such as x `+ y or list@[3]. But in this case make all the standard operators also be accessible by using the same symbol so templates will be able to differentiate them.

Operator overloading is, also, one of the few ways that you can extend one of the builtin types.

> For that latter operator, I would say that I would like to have
> the possibility to be able to define one or two operator among
> <, <¸=, > and >= and have the compiler generate the others
> so that the compiler could generate more efficient code in
> some cases (one comparison instead of 2) except if you can
> tell me that the compiler is smart enough to do the optimisation
> itself...

The compiler if given enough information can eliminate double-negatives or even single negatives in the generated code when it comes to comparisons and branching.  Most compilers routinely do this.  If the compiler can't optimize through cmp it may have to do extra work at runtime.

Yeah, all you need is one of < and one of =, or one of <=.  I wouldn't be surprised if any one of the six can be used to generate all the others. From < you can derive a form of =.

But I'd allow explicit specification of any or all of them.  Some very complicated comparison (probably bending the rules) might need it.

In fact you could represent inexact types by starting off by defining
operator <=.  Well, > means it's not <=.  If a <= b and b <= a, it's
probably ==.  If not a <= b and not b <= a, it's unordered.
I see a logic table forming here.

And if you can figure out all 6, you can automatically generate a cmp()
function from that.

BTW cmp() really only needs to be able to return 3 'bits' of data...  ==
(Z), < (S), ? (O).  You can build jae out of !jb, etc.

Ideally cmp wouldn't be a member function, so you could specify the operands in either order... currently you'd have to invert the logic when you swap operands.

void cmp(in T a, in T b,
               out bit Z, out bit S, out bit O);

I bet Walter is grinning.

Sean