www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3481] New: PATCH: opPow(), x ^^ y as a power operator

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481

           Summary: PATCH:  opPow(), x ^^ y as a power operator
           Product: D
           Version: 2.036
          Platform: Other
        OS/Version: All
            Status: NEW
          Keywords: patch
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: clugdbug yahoo.com.au


--- Comment #0 from Don <clugdbug yahoo.com.au> 2009-11-06 13:03:01 PST ---
Created an attachment (id=492)
Patch against DMD2 svn 241

Requests for an exponential operator have come up numerous times on the
newsgroup.

This patch introduces a new binary operator ^^ which performs exponentiation:
x ^^ y is pow(x, y).
Likewise x ^^= y is  x = pow(x, y).
The corresponding overloaded operators are opPow, opPow_r, and opPowAssign.

In the patch, ^^ is supported for integral and floating-point types.
Two special cases are supported:   
x ^^ 1   becomes x;
x ^^ 0.5 becomes sqrt(x);
x ^^ y   becomes pow(x, y);

This requires pow() and/or sqrt() to be defined, typically by importing
std.math.
IE, this is just syntax sugar.

BUGS: I'm translating x^^=y into x = pow(x, y). This means x gets evaluated
twice.

If this patch is accepted, there is much that can be done with the
implementation.
Most importantly by adding back-end support for x ^^ 2.
However, this simple implementation would give us the semantics.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


David Simcha <dsimcha yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dsimcha yahoo.com


--- Comment #1 from David Simcha <dsimcha yahoo.com> 2009-11-06 13:07:53 PST ---
I've been wanting an exponentiation operator since the Stone Age, but it seemed
like too small an issue to really make a point about.  This is terrific. 
However, can we at least consider making ^ the exponentiation op and moving xor
to ^^?  Yes, it breaks C compatibility, but who the heck really uses bitwise
xor except in really low-level code anyhow?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei metalanguage.com


--- Comment #2 from Andrei Alexandrescu <andrei metalanguage.com> 2009-11-06
13:16:46 PST ---
Sweet. Suggestion: rewrite x^^=y into powAssign(x, y) and define powAssign
appropriately, e.g.:

ref B powAssign(B, E)(ref B b, E e) if (isNumeric!B && isNumeric!E);

That way you don't need any trick to evaluate x only once etc.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #3 from Don <clugdbug yahoo.com.au> 2009-11-06 13:48:51 PST ---
(In reply to comment #1)
 I've been wanting an exponentiation operator since the Stone Age, but it seemed
 like too small an issue to really make a point about.  This is terrific. 
 However, can we at least consider making ^ the exponentiation op and moving xor
 to ^^?  Yes, it breaks C compatibility, but who the heck really uses bitwise
 xor except in really low-level code anyhow?

That's not possible, because things like int y = x ^ 2; would continue to compile, but silently change meaning. x ^^ y causes no problems, because it never had a meaning. I agree it's unfortunate that C grabbed the best symbols and used them for some relatively obscure operations (~ is a classic example) -- but it's too late now. I actually think we're lucky that ^^ is available. (In reply to comment #2)
 Sweet. Suggestion: rewrite x^^=y into powAssign(x, y) and define powAssign
 appropriately, e.g.:
 
 ref B powAssign(B, E)(ref B b, E e) if (isNumeric!B && isNumeric!E);
 
 That way you don't need any trick to evaluate x only once etc.

It's not really a big problem to do the whole thing properly. I just implemented the bare minimum to get started. Really, it should support constant folding, and generate back-end code for squaring, etc. That's not technically difficult, but it involves changes to many different bits of code in the compiler, which makes it a difficult patch for Walter to evaluate and integrate (and hence, less likely to be accepted). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #4 from Leandro Lucarella <llucax gmail.com> 2009-11-06 13:51:45
PST ---
I'm sorry to bring the bike shed discussion here, but I would like to consider
** exponentiation. The reason is that writing ^^ for people with keyboards with
"dead keys" (to write accents for example) is very hard, because you have to
write "^" like this: shift+6 space (3 keystrokes), or even worse (unless you
use Emacs ;): shift+alt_gr+6.

I'm not sure if ** is even possible (because of pointers), but in case it is, I
will like you to give it a thought.

This is, of course, a minor detail. I like the idea of introducing an
exponentiation operator, I just don't feel very well about depending on
importing any module, but if that can be changed/fixed in the future, it's fine
with me.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com


--- Comment #5 from Stewart Gordon <smjg iname.com> 2009-11-07 18:47:17 PST ---
(In reply to comment #1)
 I've been wanting an exponentiation operator since the Stone Age, but it seemed
 like too small an issue to really make a point about.  This is terrific. 
 However, can we at least consider making ^ the exponentiation op and moving xor
 to ^^?  Yes, it breaks C compatibility, but who the heck really uses bitwise
 xor except in really low-level code anyhow?

Are we going to change around the other bitwise vs. logical operators as well? Confusion with the bitwise operators is why I'm against the choice of ^ or ^^ for exponentiation. Sooner or later, someone's going to expect ^^ to be the logical xor operator. But I don't know what would be a good symbol for it. I'm not sure I've ever really liked **, aside from the current meanings of those two characters in sequence. Maybe if only ↑ had remained on keyboards beyond ZX Spectrum days.... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 07 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #6 from Don <clugdbug yahoo.com.au> 2009-11-07 22:26:45 PST ---
(In reply to comment #5)
 (In reply to comment #1)
 I've been wanting an exponentiation operator since the Stone Age, but it seemed
 like too small an issue to really make a point about.  This is terrific. 
 However, can we at least consider making ^ the exponentiation op and moving xor
 to ^^?  Yes, it breaks C compatibility, but who the heck really uses bitwise
 xor except in really low-level code anyhow?

Are we going to change around the other bitwise vs. logical operators as well? Confusion with the bitwise operators is why I'm against the choice of ^ or ^^ for exponentiation. Sooner or later, someone's going to expect ^^ to be the logical xor operator.

Logical xor is already in the language, its symbol is !=.
 But I don't know what would be a good symbol for it.  I'm not sure I've ever
 really liked **, aside from the current meanings of those two characters in
 sequence.  Maybe if only ↑ had remained on keyboards beyond ZX Spectrum
 days....

-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 07 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #7 from Stewart Gordon <smjg iname.com> 2009-11-08 06:55:47 PST ---
(In reply to comment #6)
 Logical xor is already in the language, its symbol is !=.

Not quite. For example, 1 != 2 evaluates to true, whereas if ^^ is defined as a logical xor, 1 ^^ 2 would evaluate to false. But if the operands are guaranteed to be boolean or at least 0 or 1, then != is effectively a logical xor. To get logical xor when other values are possible, one would have to do something like negate the operands. So essentially, a ^^ b would be equivalent to !a != !b. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 08 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com


--- Comment #8 from Walter Bright <bugzilla digitalmars.com> 2009-11-28
15:42:40 PST ---
Thoughts on if the ^^= variant is needed?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #9 from Walter Bright <bugzilla digitalmars.com> 2009-11-28
20:59:29 PST ---
I checked in changes as 269, but only for the ^^.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #10 from Sobirari Muhomori <dfj1esp02 sneakemail.com> 2009-11-30
07:01:11 PST ---
(In reply to comment #4)
 I'm sorry to bring the bike shed discussion here, but I would like to consider
 ** exponentiation. The reason is that writing ^^ for people with keyboards with
 "dead keys" (to write accents for example) is very hard, because you have to
 write "^" like this: shift+6 space (3 keystrokes), or even worse (unless you
 use Emacs ;): shift+alt_gr+6.

If remeber it correctly, you don't have to type space in this case, just hit shift+6 two times. Yes, the first hit will be the dead key hit, but the second will yield ^^ at once. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 30 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Leandro Lucarella <llucax gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |llucax gmail.com


--- Comment #11 from Leandro Lucarella <llucax gmail.com> 2009-11-30 14:01:10
PST ---
(In reply to comment #10)
 (In reply to comment #4)
 I'm sorry to bring the bike shed discussion here, but I would like to consider
 ** exponentiation. The reason is that writing ^^ for people with keyboards with
 "dead keys" (to write accents for example) is very hard, because you have to
 write "^" like this: shift+6 space (3 keystrokes), or even worse (unless you
 use Emacs ;): shift+alt_gr+6.

If remeber it correctly, you don't have to type space in this case, just hit shift+6 two times. Yes, the first hit will be the dead key hit, but the second will yield ^^ at once.

Not with my keyboard configuration, I can hit Shift+6 twice, but that yields only one ^, so I have to press Shift+6 four times to get ^^ :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 30 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


torhu yahoo.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |torhu yahoo.com


--- Comment #12 from torhu yahoo.com 2009-12-02 12:13:51 PST ---
(In reply to comment #11)
 Not with my keyboard configuration, I can hit Shift+6 twice, but that yields
 only one ^, so I have to press Shift+6 four times to get ^^ :)

I have to do that too, but only on Linux. On Windows, it only takes two presses. This is using a Norwegian keyboard, where the caret is on a different key, but you still have to hold down the shift key. Maybe it's time to upgrade to Windows? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 02 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #13 from Sobirari Muhomori <dfj1esp02 sneakemail.com> 2009-12-04
05:31:01 PST ---
It's strange, I tried english-international and french layouts - they work as I
described.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 04 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #14 from Walter Bright <bugzilla digitalmars.com> 2009-12-06
00:54:25 PST ---
Fixed dmd 2.037

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481


Witold Baryluk <baryluk smp.if.uj.edu.pl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |baryluk smp.if.uj.edu.pl


--- Comment #15 from Witold Baryluk <baryluk smp.if.uj.edu.pl> 2009-12-08
21:35:13 PST ---
Just wanted to write: Thanks!

I have about 10 classes with already deffinied opPow just waiting to this for
years.


About Walters question about opPowAssgn, i have few place where i'm for.
example squering in place,  or  (in. for computing exponent of interval
matrix), this isn't actually inplace, but makes code more readble, other i
example in my libraries i see units library, where i see something like this:

    Self opPowAssign(int b) {
        if (b >= 0) {
            nom = pow(cast(int)nom, b);
            denom = pow(cast(int)denom, b);
        } else {
            auto newnom = pow(cast(int)denom, -b);
            denom = pow(cast(int)nom, -b);
            nom = newnom;
        }
        return this;
    }

Clearly first can use opPowAssign, of course in such simple example compiler
should be detect that x = x ^^ y, for simple types can be done in place. And
this opPowAssign is used in few places also.

Or clearly like this:

    Self opPowAssign(int b) {
        nom ^^= b;
        denom  ^^= b;
        if (b < 0) {
            swap(nom, denom);
        }
        return this;
    }


I have also few places with something like:

  new_step = pow(previous_step, f(x))

  it can be changed to: step ^^= f(x). 

and new_step is not nacassarly float or double, it can be slightly more complex
structure like interval vector (and exponentation of it can be done in-place).


I also think that sometimes pepole will have not enaugh operators, and for the
sake of consistency it is good to have opPowAssign. :) Not nacassarly good for
clearity of code if it will use ALL opXAssign for very diferent things.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 08 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3481



--- Comment #16 from Witold Baryluk <baryluk smp.if.uj.edu.pl> 2009-12-08
22:11:40 PST ---
It is also usefull to have opPowAssign for vector operations:

 float a[],. b[];
  a[] ^^= 2;
  a[] ^^= b[];

It should be easier to compiler to generate better code, than from this:
  a[] = a[] ^^ 2;
  a[] = a[] ^^ b[];

BTW is ^^ supported as operator in array operations? IT definietly SHOULD.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 08 2009