🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

13 total messages Started by Bjarne Stroustrup Sat, 12 Sep 1992 18:30
Exponentiation operator proposal
#154
Author: Bjarne Stroustrup
Date: Sat, 12 Sep 1992 18:30
67 lines
2378 bytes
Comments on Mat Austern's proposal for an exponentiation
operator in C++ (posted to comp.lang.std and, I think,
also to comp.lang.c++).

(1) I think overloading and inlining can be used a bit
	more effectively than is assumed in tht proposal.
	For example:

	double pow(double,double); // what C gives us
	double _pow(double,int); // general pow(double,int)

	inline double pow(double d, int i) // inlining to catch
					   // important special cases
	{
		if (i == 2) return d*d;
		else if (i == 3) return d*d*d;
		else _pow(d,i);
	}
	
	
	void f(double d, int i)
	{
		pow(d,d);
		pow(d,i);
		pow(d,2);
		pow(d,3);
		pow(d,4);
	}

	will generate better code for small integer powers.
	This technique is fairly gaeneral and does not depend on
	cleverness beyond the average C++ compiler.

	I agree that a clever compiler can do better, but for now
	this technique might be helpful to some.

(2) I think we could actually get ** as the exponentiation operator.

	Consider the well-known counter-example:

		int a;
		int* p;

		a**b;

	For C compatibility, a**b must mean a * (*b). However,
	with a minor sleigh of hand this can be achieved even
	if we introduce and exponentiation operator represented
	by the single token **.

	All we need to do is to say that the exponentiation
	operator ** given a first operand `a' of arithmetic type
	and a second operand `b' of pointer type (that is, `a**b')
	mean multiply the first operand with the dereference value
	of the second operand (that is, `a*(*b)'). This would not
	be quite 100% compatible because a*b**p where p is a pointer
	would mean a*(b*(*p)) rather than (a*b)*(*p), but I suspect
	that it would be compatible enough.

	Similarly the token ** when used in a declarator must mean
	* * (that is pointer to pointer.

	
	I think this would take care of the compatibility problems.
	There may be other minor details to consider, but I don't
	see any insurmountable problems.
Re: Exponentiation operator proposal
#157
Author: Karl Heuer
Date: Sun, 13 Sep 1992 19:35
33 lines
2132 bytes
In article <23660@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:
>Comments on Mat Austern's proposal for an exponentiation operator

I missed that one, but I've posted about exponentiation a few times myself.

>(1) I think overloading and inlining ...

My only objection to this method (other than the perceived aesthetic
superiority of an infix operator) is that the later example
>	void f(double d, int i) { ... pow(d,i); ... }
inline-expands to something that always runtime-compares the variable i with
certain small integers before invoking the true function _pow().  In some
sense it would be better to do this only when i is a constant (in which case
it's a compile-time compare), and have the non-constant-exponent case simply
call the true function immediately.

This could be accomplished with one addition to the language:
	isconstant(expr) - an operator that returns 1 if expr is a
	constant expression, or 0 if not.  If the operand involves
	formal parameters to an inline function, the actual arguments
	are used.

>(2) I think we could actually get ** as the exponentiation operator.
>[By defining `**' to have semantics of TIMES FETCH when the right operand
>is a pointer]

I considered this when I wrote my exponentiation essay.  I decided that it
might be possible, but it's way too confusing!  This would be a kludge of the
highest order.  It's much better to use syntax that's not already taken --
I've adopted "*^", as suggested by someone else some years ago.  (A hybrid of
"**" and "^", sort of.)

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint
Re: Exponentiation operator proposal
#158
Author: Robert I Ransbottom
Date: Sun, 13 Sep 1992 23:58
40 lines
2110 bytes
In article <1992Sep13.193507.27813@ima.isc.com> karl@ima.isc.com (Karl Heuer) writes:
>In article <23660@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:

>>Comments on Mat Austern's proposal for an exponentiation operator

>>[By defining `**' to have semantics of TIMES FETCH when the right operand

>I considered this when I wrote my exponentiation essay.  I decided that it
>might be possible, but it's way too confusing!  This would be a kludge of the
>highest order.  It's much better to use syntax that's not already taken --
>I've adopted "*^", as suggested by someone else some years ago.  (A hybrid of
>"**" and "^", sort of.)

I agree ** is confusing, given the potential frequency of both "dat**ptr" and
"dat**dat" it seems like a waste to deciphering such.  The proponents
of **expon want a convenience. 

I think that ^^ would be more satisfying to both pointer-ers and math-ers.  

    1. Its not already taken!
    2. Its not already taken!
    3. Its not already taken!
    .   .   .    .      .
    .   .   .    .      .
    n. Its easier to type than Karl's *^. 
    n+1. No more damaging if mistyped.
    n+2. The contexts of exponentiation and exclusive-or have less overlap
    	than multiplication & indirection and exponentiation.

My vote is behind a keyword like

	operator consistent { *=, /=, -=, += }

which would shorthand consistent derivatives  X= from X and =.
The longhand is simple enough to generate, but is more difficult to
read/verify given alien code.
-- 
rr@world.std.com  Robert Ransbottom

"Maintaining correct attributions is extremely important." -- anonymous
Re: Exponentiation operator proposal
#160
Author: Karl Heuer
Date: Mon, 14 Sep 1992 07:39
7 lines
862 bytes
In article <BuJJxs.8Hx@world.std.com> rr@world.std.com (Robert I Ransbottom) writes:
>[How about spelling it "^^", then?]

Some people still hope to adopt that symbol for boolean xor.  (I don't,
but I don't want to stand in the way of those who do.)

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint
Re: Exponentiation operator proposal
#163
Author: Bjarne Stroustrup
Date: Mon, 14 Sep 1992 14:27
47 lines
2704 bytes

karl@ima.isc.com (Karl Heuer) writes

 > >(2) I think we could actually get ** as the exponentiation operator.
 > >[By defining `**' to have semantics of TIMES FETCH when the right operand
 > >is a pointer]

 > I considered this when I wrote my exponentiation essay.  I decided that it
 > might be possible, but it's way too confusing!  This would be a kludge of the
 > highest order.  It's much better to use syntax that's not already taken --
 > I've adopted "*^", as suggested by someone else some years ago.  (A hybrid of
 > "**" and "^", sort of.)

Of course it is a hack. It is a compatibility hack of the first order,
but I see few TECHNICAL problems with it.

and  rr@world.std.com (Robert I Ransbottom) writes

 > I agree ** is confusing, given the potential frequency of both "dat**ptr" and
 > "dat**dat" it seems like a waste to deciphering such.  The proponents
 > of **expon want a convenience. 
 > 
 > I think that ^^ would be more satisfying to both pointer-ers and math-ers.  
 > 
 >     1. Its not already taken!
 >     .   .   .    .      .
 >     n. Its easier to type than Karl's *^. 

The reason I mentioned ** is that I think that every alternative mentioned
so far has something wrong with it. I see ^ as xor and ^^ bothers me.
As it happens *^ doesn't bother me but my feeling was that 99% of the
deamand for an exponentiation operator comes from current or past Fortran
users and - in my experience - they always ask for ** and are unsatisfied
with the explanations of why they can't have that syntax.

How frequent is a**p anyway? (has anyone got any data?) How confusing
would it really be? Many people use spaces to clarify (to their eyes,
if not to everyone else's) code, e.g. a * *p. Also, not all overloading
creates confusion, especially when identifier names are chosen with
a minimum of care (want would x**e mean? a**xptr mean?). I doubt the
case is clear cut.

I am not arguing that ** is THE right solution, but that given the
demand for it and the lack of ginuinely nice alternatives ** should
not be written off without a thought and/or in the belief that it
is technically infeasible to provide it.
Re: Exponentiation operator proposal
#165
Author: Hallvard B Furuseth
Date: Mon, 14 Sep 1992 19:53
22 lines
1549 bytes
Sorry, I just cancelled an article where a rather essential part was
deleted (I just intended to move it...)  Here is next attempt -

In article <23660@alice.att.com> bs@alice.att.com (Bjarne Stroustrup) writes:

> (2) I think we could actually get ** as the exponentiation operator.
> (...)
>	   All we need to do is to say that the exponentiation
>	   operator ** given a first operand `a' of arithmetic type
>	   and a second operand `b' of pointer type (that is, `a**b')
>	   mean multiply the first operand with the dereference value
>	   of the second operand (that is, `a*(*b)').

The few times I use a**b, a and *b are usually class objects.  operator*
could be cross product or a set operation.  b.operator*() may exist too,
but to me that is less important.  To allow both this and Complex
operator**(Complex&,Complex&), I think the rule must be something like
"** is exponentiation unless that is an error".  I do not volunteer to
write the parser though.  A binary operator~ is my favorite.
--

Hallvard
Re: Exponentiation operator proposal
#167
Author: Matt Austern
Date: Mon, 14 Sep 1992 22:50
110 lines
6163 bytes
Recently, Bjarne Stroustrup suggested that it would be possible for
the exponentiation operator to be denoted **.  At first sight this
appears to be impossible, since ** already has a very different
meaning in C++, and previous discussions of an exponentiation operator
(mine included) have dismissed this possibility without further
analysis.

This has been excessively hasty.  Exponentiation is only defined if
both operands are of a numeric type; conversely, ** is currently
meaningful only if it precedes a pointer.  There is no overlap, so it
might, therefore, be possible to use type information to disambiguate
these different uses of **.

Specifically, we might consider the following proposal:

--------------------------------------------------------------------

    Two new tokens, ** and **=, will be added to the C++ language.  **
    will be both a unary and a binary operator.  Unary ** will have
    the same precedence as the other unary operators, and binary **
    will have a new precedence level between the multiplicative
    operators and the pointer-to-member operators.

    Unary ** is defined only for an operand which is a pointer to a
    pointer, and it will mean to dereference that operand twice.

    If the arguments to binary ** are both of a numeric type, then it
    denotes exponentiation, and its semantics will be those described
    by my earlier proposal.  If its first operand is of a numeric type
    and its second is a pointer to a number, then it means to multiply
    the first operand by the contents of the second.  For other
    combinations of argument types, binary ** is undefined.

    **= is defined only for the case where the first operand is a 
    modifiable lvalue of a numeric type and the second operand is an
    object of a numeric type; it is defined the same way as the other
    op= operators.

    **=, and unary and binary **, may be overloaded by the user if 
    at least one argument is a class.

---------------------------------------------------------------------- 

This proposal does, at least, implement ** as an exponentiation
operator while continuing to allow its current uses.  However, it
presents several difficulties.

First, it breaks existing code.  To see why it must do so, notice that
in current C++, ** is not a single token; it is a sequence of either a
binary operator followed by a unary operator, or else two unary
operators.  The difficulty is that the binary and the unary operators
have different precedence.  So, in particular, consider the expression
			x/y**p,
which, by the current language definition, is equivalent to
			(x/y) * (*p).
According to the proposal above, however, ** is a single token with a
precedence higher than division, so this expression will mean
			x / (y * (*p)).
I don't know how much code actually contains expressions like this,
but it isn't unreasonable to assume that at least some does.

Second, even in code which won't be broken by this change in the
behavior of **, users will have to examine their code to make sure
that it still means what they thought it did.  ** is a common enough
character sequence (consider, for example, the idiom **argv) that most
programmers will at least have to glance at their code, even if
nothing actually needs to be changed.

Third, the disambiguation rules don't go far enough: they solve the
problem for built-in types, but not for class types.  Users who define
``smart pointers'' will want the dereference operator to work the same
way for their smart pointers as for ordinary C pointers, so, if they
overload unary * to mean smart pointer dereference, they will
similarly be forced to overload unary and binary **.  This imposes an
additional burden on people who use a rather common programming
technique.

** does have one potential advantage over *^ as an exponentiation
operator: that is how exponentiation is denoted in FORTRAN.  I regard
that as a small advantage, however; there is nothing particularly
natural about FORTRAN's use of that symbol, and I believe that
scientific programmers could get used to *^ just as easily as they got
used to the once-unfamiliar **.  In fact, it isn't completely clear to
me that ** would really be more readable as a C++ exponentiation
operator than *^ would be: scientific programmers, like other
programmers, would have to cope with the multiple meanings of **.

I believe that an exponentiation operator would be of genuine benefit
to C++ scientific programmers, and I believe that we who write
scientific code are justified in asking that it be included.  I don't
think, however, that we are justified in asking for a change to the
language that makes life harder for other C++ programmers.  Using **
to denote exponentiation does exactly that: it changes the meaning of
legal C++ code, and it makes a useful programming technique more
difficult.

It is possible to implement an exponentiation operator so that the
extension to the language will have no effect at all for people who
don't deliberately use the new feature.  This is a better idea.





--
Matthew Austern                   Just keep yelling until you attract a
(510) 644-2618                    crowd, then a constituency, a movement, a
austern@lbl.bitnet                faction, an army!  If you don't have any
matt@physics.berkeley.edu         solutions, become a part of the problem!
Re: Exponentiation operator proposal
#166
Author: Juhana Kouhia
Date: Tue, 15 Sep 1992 05:42
18 lines
993 bytes
Hi,

I'm very new in C++ world; I have not done any programs so far;
and I'm currently reading C++ Primer books on chapter 3   :-)

Instead of making exponential operator; I would like to get
a new basic operation which allows programmer to define new
operations like 'a ** b'; that is, the '**' is defined.
('a pow b' is also good.)

The operation '**' may hide freely some other operations;
like, maybe, 'c ** **p' which should be written 'c ** (**p)'
(maybe poor example; I write always clearly anyway and don't
study those ****a*******b**** hacker tricks).


Juhana Kouhia
Re: Exponentiation operator proposal
#168
Author: Dag Bruck
Date: Tue, 15 Sep 1992 06:16
103 lines
4310 bytes
In <comp.std.c++,comp.lang.c++> bs@alice.att.com (Bjarne Stroustrup) writes:
>
>How frequent is a**p anyway?

I asked the net how frequent exponentiation is, and got very few
answers back; there are some interesting observations, though. Nobody
took the offer to look at the really big FORTRAN libraries.  In my
view the results are inconclusive at this point.

I haven't looked at the latest version of the proposal, but I strongly
ask the authors to support their requests with solid user's experience
from related applications, not necessarily in C++.  If you can show
that exponentiation is more common than division (just as an example),
that is indeed a very strong argument.  Sorry to nit pick if you have
already done it.

In any case, here follows the answers I got, somewhat edited for
clarity:

			-- Dag

========================================================================

From: matt@physics.berkeley.edu (Matt Austern)
Subject: Re: Power operator for C++
Date: 6 Jul 92 14:28:39
Organization: Lawrence Berkeley Laboratory (Theoretical Physics Group)

In article <1992Jul5.133125.5575@lth.se> dag@control.lth.se (Dag Bruck) writes:

> I ask someone with access to a lot of numerical code (perhaps written
> in FORTRAN) to do us a favour: gather some statistics that can tell us
> how common exponentiation is compared to other operators, such as,
> addition, subtraction, multiplication and division.  Compared to
> square root?

I just did a bit of grepping on a moderate-sized (30,000 lines)
Fortran program, called Papageno.  I suspect that it is fairly typical
of code used in particle physics.

Some statistics:
	Operator	Number of lines containing operator
	--------	-----------------------------------
	  total		32000
	  +		10711
	  *		6805
	  -		6253
	  /		3382
	  **		1481

The result, then, is that exponentiation is about half as common in
this program as division.  To me, at least, this qualifies as
"common".  Certainly nobody would suggest that a division operator is
unnecessary just because it is used only half as much as subtraction!

(Many lines uses exponentiation more than once; in total, the operator
** is used 4496 times in PAPAGENO.)

Looking over the code, by the way, it seems that the vast majority of
the time, ** is used to raise a quantity to an integral power.  (I
didn't gather statistics; that would require more effort than a simple
grep!)  This suggests that pow(double,double) is not a good
substitute; a better substitute would be pow(double,int), which is not
in the standard library.


From: maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller)
Subject: Re: Power operator for C++
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Mon, 6 Jul 1992 06:22:57 GMT

	I have a program which calculates gaussian dispersion of
toxic materials in air. In the bits that do calculations work,
here are the scores in terms of line counts
[I did grep token file | wc]

Lines total:	172
+		27
-		24
*		25
/		32
%		2
=,==,etc	79
pow		13
fsqr		12	// inline to square number
sqrt		3

IMHO if you cheat a bit and add the last three you get 28, second
only to use of '/'. I'd be happy to post the code if that was
desired [minus flames on style :-)



Date: Tue, 7 Jul 92 17:11:44 -0700
From: Paul Kunz <pfkeb@KAON.SLAC.Stanford.EDU>
Subject: Power operator for C++

   I asked Bill Atwood about what happen to **2 type constructs in
Gismo.   He looked puzzled.   He agrees that in the FORTRAN programs
the code is littered with **2, but he's not sure what happened to
such constructs in the Gismo C++ code.   Perhaps they have disappeared
into member functions of some base or low level classes so they are
not so visible anymore.   We don't know.
Re: Exponentiation operator proposal
#169
Author: Juergen Menden
Date: Tue, 15 Sep 1992 09:41
9 lines
742 bytes
Hi,
just an idea: how about 
	a ^^ b; 



-- 
Juergen Menden			menden@informatik.tu-muenchen.de
Re: Exponentiation operator proposal
#171
Author: Paul Lucas
Date: Tue, 15 Sep 1992 14:00
43 lines
2576 bytes
In <1992Sep15.054226.4126@cc.tut.fi> jk87377@cc.tut.fi (Juhana Kouhia) writes:

>Hi,

>I'm very new in C++ world; I have not done any programs so far;
>and I'm currently reading C++ Primer books on chapter 3   :-)

>Instead of making exponential operator; I would like to get
>a new basic operation which allows programmer to define new
>operations like 'a ** b'; that is, the '**' is defined.
>('a pow b' is also good.)

*****>	The short answer is that it's a _real_ pain.  The somewhat
	longer answer is that making new operators means that you have
	to also establish the precedence and associativity of the new
	operator relative to all the other operators *AND* any other
	operators created by other people.  Every time an operator is
	added, the hierarchy would have to be readjusted.

	For new operators, the precedence and associativity may seem
	arbitary at the time of creation, but it may later be realised,
	after experience, that it could have been done better...of
	course it's too late to change it now because code would break.

	Also, if you were to use library X and library Y, each could use
	the same operator for different reasons, and the two operators
	were developed without regard to the others precedence and
	associativity; how would the compiler resolve this?  (I'm not
	looking for people to show how smart they are here by telling me
	how a compiler could resolve this...the point is that even if
	the compiler could do it, most _people_ would have a tough time
	looking at the code.)

	It's more trouble than its worth.  The _point_ of operator
	overloading is to give an operator a _natural_ extension to
	another type.  People shouldn't sit around trying to figure out
	how to force an operator (square peg) to be used for a new type
	(round hole).  If the operator's use in a new context isn't
	intuitively obvious, forget it and use function-notation.
-- 
	- Paul J. Lucas				University of Illinois	
	  AT&T Bell Laboratories		at Urbana-Champaign
	  Naperville, IL			pjl@cs.uiuc.edu
Re: Exponentiation operator proposal
#173
Author: Bill Hosken
Date: Tue, 15 Sep 1992 14:51
50 lines
2895 bytes
In article <1992Sep15.140027.17387@sunb10.cs.uiuc.edu>, pjl@sparc10.cs.uiuc.edu (Paul Lucas) writes:
> In <1992Sep15.054226.4126@cc.tut.fi> jk87377@cc.tut.fi (Juhana Kouhia) writes:
> 
> >Hi,
> 
> >I'm very new in C++ world; I have not done any programs so far;
> >and I'm currently reading C++ Primer books on chapter 3   :-)
> 
> >Instead of making exponential operator; I would like to get
> >a new basic operation which allows programmer to define new
> >operations like 'a ** b'; that is, the '**' is defined.
> >('a pow b' is also good.)
> 
> *****>	The short answer is that it's a _real_ pain.  The somewhat
> 	longer answer is that making new operators means that you have
> 	to also establish the precedence and associativity of the new
> 	operator relative to all the other operators *AND* any other
> 	operators created by other people.  Every time an operator is
> 	added, the hierarchy would have to be readjusted.
> 
> 	For new operators, the precedence and associativity may seem
> 	arbitary at the time of creation, but it may later be realised,
> 	after experience, that it could have been done better...of
> 	course it's too late to change it now because code would break.
> 
> 	Also, if you were to use library X and library Y, each could use
> 	the same operator for different reasons, and the two operators
> 	were developed without regard to the others precedence and
> 	associativity; how would the compiler resolve this?  (I'm not
> 	looking for people to show how smart they are here by telling me
> 	how a compiler could resolve this...the point is that even if
> 	the compiler could do it, most _people_ would have a tough time
> 	looking at the code.)
> 
> 	It's more trouble than its worth.  The _point_ of operator
> 	overloading is to give an operator a _natural_ extension to
> 	another type.  People shouldn't sit around trying to figure out
> 	how to force an operator (square peg) to be used for a new type
> 	(round hole).  If the operator's use in a new context isn't
> 	intuitively obvious, forget it and use function-notation.

To illustrate these points, consider the << operator.

cout << 1 ? 2 : 3 ;

The result is a little hard to figure out until you remember
the precedence rules.

---------------
Bill.
Re: Exponentiation operator proposal
#176
Author: Gnanasekaran Swaminathan
Date: Tue, 15 Sep 1992 20:18
50 lines
2220 bytes
matt@physics2.berkeley.edu (Matt Austern) writes:

: I believe that an exponentiation operator would be of genuine benefit
: to C++ scientific programmers, and I believe that we who write
: scientific code are justified in asking that it be included.  I don't
: think, however, that we are justified in asking for a change to the
: language that makes life harder for other C++ programmers.  Using **
: to denote exponentiation does exactly that: it changes the meaning of
: legal C++ code, and it makes a useful programming technique more
: difficult.
: 
: It is possible to implement an exponentiation operator so that the
: extension to the language will have no effect at all for people who
: don't deliberately use the new feature.  This is a better idea.

Did you consider operator () for exponentiation?
It seems to have correct precedence and doesn't need new tokens to be
introduced.

// if op () is available for exp
double e= -10(2); // e = -100.0
double d=10;
double *p = &e;

e = d(3) - (*p)(2) + d + 3; // e = -8987.0

// status quo
class Double {
	double d;
public:
	Double(double f): d(f) {}
	operator double () { return d; }
	Double operator - () { return -d; }
	Double operator () (int i) { ... }
	Double operator () (double f) { return pow(d,f); }
	// other ops ...
};

Double a(10);  // a = 10.0
double d=a(5); // d = 10000.0

a = a(3.0)*2.5; // a = 2500.0

Double b(2); // b = 2
a = -b(4) + 3*b(3) - 2*b(2) + b + 3; // a = 5.0

Similary you can define your own Int as well and use it wherever
you want int and exp op. 

-Sekar
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads