www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Custom binary operators

reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
Is there any way with D to define custom binary operators for user-defined 
types?  I'm thinking of examples like MATLAB/Octave using the operators .+, .-, 
etc. to define element-wise addition, subtraction, etc. of matrices.

AFAICS just doing something like

     auto opBinary(string op, T)(T rhs)
         if (op == ".+")
     {
         ...
     }

... won't work, because the parser won't accept a code line like

     auto c = a .+ b;

... but is there some way to make this work?

Assuming that it's not possible to define custom operators in regular code, I 
guess the alternative is to use templates to ensure an override of the regular
+ 
operator?
Dec 28 2013
parent reply "Dicebot" <public dicebot.lv> writes:
AFAIK it is intentionally banned to constrain operator 
overloading abuse.
Dec 28 2013
next sibling parent reply Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 28/12/13 16:24, Dicebot wrote:
 AFAIK it is intentionally banned to constrain operator overloading abuse.
Ahh, makes sense. But isn't it possible to do something with templates that would allow for something like, auto a = matrix(...); auto b = matrix(...); auto c = ElementWise!("a * b"); ... where the ElementWise template would ensure that the binary operation is applied successively to corresponding pairs of elements from the matrices?
Dec 28 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 28 December 2013 at 16:33:24 UTC, Joseph Rushton 
Wakeling wrote:
 On 28/12/13 16:24, Dicebot wrote:
 AFAIK it is intentionally banned to constrain operator 
 overloading abuse.
Ahh, makes sense. But isn't it possible to do something with templates that would allow for something like, auto a = matrix(...); auto b = matrix(...); auto c = ElementWise!("a * b"); ... where the ElementWise template would ensure that the binary operation is applied successively to corresponding pairs of elements from the matrices?
how about: a.elementWise * b where a.elementWise returns a wrapper struct around a that implements elementwise arithmetic as opposed to the normal arithmetic. The operators would return instances of Matrix, not elementWise, to avoid accidentally spilling a Matrix.ElementWise struct in to ensuing code unintentionally. With a shorter alias it's rather neat. auto e = ((a .EW* b) .EW/ c ) * d;
Dec 28 2013
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 28/12/13 18:50, John Colvin wrote:
 how about:

 a.elementWise * b

 where a.elementWise returns a wrapper struct around a that implements
 elementwise arithmetic as opposed to the normal arithmetic.

 The operators would return instances of Matrix, not elementWise, to avoid
 accidentally spilling a Matrix.ElementWise struct in to ensuing code
 unintentionally. With a shorter alias it's rather neat.

 auto e = ((a .EW* b) .EW/ c ) * d;
That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work à la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-(
Dec 28 2013
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Dec 28, 2013 at 07:35:00PM +0100, Joseph Rushton Wakeling wrote:
 On 28/12/13 18:50, John Colvin wrote:
how about:

a.elementWise * b

where a.elementWise returns a wrapper struct around a that implements
elementwise arithmetic as opposed to the normal arithmetic.

The operators would return instances of Matrix, not elementWise, to
avoid accidentally spilling a Matrix.ElementWise struct in to ensuing
code unintentionally. With a shorter alias it's rather neat.

auto e = ((a .EW* b) .EW/ c ) * d;
That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-(
The other way is to use a compile-time DSL, which lets you implement whatever operators you want in whatever syntax you fancy. T -- Today's society is one of specialization: as you grow, you learn more and more about less and less. Eventually, you know everything about nothing.
Dec 28 2013
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 28 December 2013 at 20:06:46 UTC, H. S. Teoh wrote:
 On Sat, Dec 28, 2013 at 07:35:00PM +0100, Joseph Rushton 
 Wakeling wrote:
 On 28/12/13 18:50, John Colvin wrote:
how about:

a.elementWise * b

where a.elementWise returns a wrapper struct around a that 
implements
elementwise arithmetic as opposed to the normal arithmetic.

The operators would return instances of Matrix, not 
elementWise, to
avoid accidentally spilling a Matrix.ElementWise struct in to 
ensuing
code unintentionally. With a shorter alias it's rather neat.

auto e = ((a .EW* b) .EW/ c ) * d;
That's a rather cool idea -- thanks for that! :-) That said, I think it'd be difficult to really justify it as a pattern for general use. If you're doing mathematical work à la MATLAB, you want a proper operator, not a trick which lets you sort of write something that looks a little like one. I'm a little disappointed there's no ready way to do this :-(
The other way is to use a compile-time DSL, which lets you implement whatever operators you want in whatever syntax you fancy. T
Yeah. To risk being glib, if you want a domain specific language, use a domain specific language. Then again, including some convenient abstraction for some common tasks while remaining within the main language is nice.
Dec 28 2013
prev sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Sat, 28 Dec 2013 15:24:31 +0000
schrieb "Dicebot" <public dicebot.lv>:

 AFAIK it is intentionally banned to constrain operator 
 overloading abuse.
That and it makes the compiler faster. -- Marco
Dec 29 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Dec 30, 2013 at 05:34:10AM +0100, Marco Leise wrote:
 Am Sat, 28 Dec 2013 15:24:31 +0000
 schrieb "Dicebot" <public dicebot.lv>:
 
 AFAIK it is intentionally banned to constrain operator 
 overloading abuse.
That and it makes the compiler faster.
[...] And discourages writing unreadable code like that C++ regex template library that turns expressions into something that's neither (numerical) expressions nor regular expressions. Operator overloading abuse at its finest. T -- "Real programmers can write assembly code in any language. :-)" -- Larry Wall
Dec 29 2013