www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opPow, opDollar

reply Don <nospam nospam.com> writes:
A little while ago I said I'd create a patch for ^^ as an 
exponentiation. A couple of people had requested that I make a post to 
the ng so they'd know when it happens. Here it is.

This is opPow(),  x ^^ y

http://d.puremagic.com/issues/show_bug.cgi?id=3481

And this is opDollar!(int dim) for multi-dimensional indexing

http://d.puremagic.com/issues/show_bug.cgi?id=3474

<attempt to avoid bikshed>
There have been long bikeshed discussions about the naming of both of 
these several times in the past. Please don't ask for name changes to x 
^ y, x ** y, opLength, or opSize: there are known problems with all of 
those. And opEnd has the problem that you expect it to be paired with an 
opBegin. opDollar is not as aesthetically pleasing as you might wish, 
but it's obvious and completely unambiguous. I think they're the best 
options we have.
Nov 07 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 A little while ago I said I'd create a patch for ^^ as an 
 exponentiation. A couple of people had requested that I make a post to 
 the ng so they'd know when it happens. Here it is.
 
 This is opPow(),  x ^^ y
 
 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
Nov 07 2009
next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an 
 exponentiation. A couple of people had requested that I make a post to 
 the ng so they'd know when it happens. Here it is.

 This is opPow(),  x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
AWESOME! Thanks a lot, Don! I've been hoping for this since I started using D. Walter Bright wrote:
 I don't understand the rationale for an exponentiation operator. It 
 isn't optimization, because pow() could become an intrinsic that the 
 compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
I don't understand the rationale for a concatenation operator. It isn't optimization, because strcat() could become an intrinsic that the compiler knows about. strcat() is well known, ~ isn't. (Java uses +) I'm not trying to be rude, I'm just trying to illustrate that the first point doesn't make a good case against an exponentiation operator. I can only speak for myself, but I use exponentiation a lot. I mostly write numerical code, and as I understand it, I'm not the only one in the community doing so. Being able to overload the exponentiation operator also makes a lot of sense. Matrices and BigInts are the first things that come to mind. -Lars
Nov 07 2009
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an 
 exponentiation. A couple of people had requested that I make a post to 
 the ng so they'd know when it happens. Here it is.

 This is opPow(),  x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice. Yes, ^^ hasn't been used for exponentiation before. Fortran used ** because it had such a limited character set, but it's not really a natural choice; the more mathematically-oriented languages use ^. Obviously C-family languages don't have that possibility.
Nov 07 2009
next sibling parent Mike James <foo bar.com> writes:
 the more mathematically-oriented languages use ^
And BASIC ;-) -=mike=-
Nov 07 2009
prev sibling next sibling parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Don wrote:
 Yes, ^^ hasn't been used for exponentiation before. Fortran used ** 
 because it had such a limited character set, but it's not really a 
 natural choice; the more mathematically-oriented languages use ^. 
 Obviously C-family languages don't have that possibility.
Haskell has three exponentiation operators in the standard library: ^, ^^, and **. They are for non-negative integral exponents, integral exponents, and floating-point exponents respectively.
Nov 07 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Matti Niemenmaa wrote:
 Don wrote:
 Yes, ^^ hasn't been used for exponentiation before. Fortran used ** 
 because it had such a limited character set, but it's not really a 
 natural choice; the more mathematically-oriented languages use ^. 
 Obviously C-family languages don't have that possibility.
Haskell has three exponentiation operators in the standard library: ^, ^^, and **. They are for non-negative integral exponents, integral exponents, and floating-point exponents respectively.
I wonder whether that's an illustration of the power or of the failure of function overloading. (Seriously.) Andrei
Nov 07 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Andrei Alexandrescu wrote:
 Matti Niemenmaa wrote:
 Don wrote:
 Yes, ^^ hasn't been used for exponentiation before. Fortran used ** 
 because it had such a limited character set, but it's not really a 
 natural choice; the more mathematically-oriented languages use ^. 
 Obviously C-family languages don't have that possibility.
Haskell has three exponentiation operators in the standard library: ^, ^^, and **. They are for non-negative integral exponents, integral exponents, and floating-point exponents respectively.
I wonder whether that's an illustration of the power or of the failure of function overloading. (Seriously.)
I'm not sure either. I don't speak Haskell, but my guess is that ^ and ^^ were meant to cut out the confusion that would happen if Word32 ^ Word32 (what weird naming conventions Haskell has!) returned an integer type but Int32 ^ Int32 returned a floating point type. But why it needs yet another for floating-point exponents, I don't know. Maybe Haskell supports only IFTI rather than true function overloading. Stewart.
Nov 07 2009
parent reply Matti Niemenmaa <see_signature for.real.address> writes:
Stewart Gordon wrote:
 Andrei Alexandrescu wrote:
 Matti Niemenmaa wrote:
 Haskell has three exponentiation operators in the standard library: 
 ^, ^^, and **. They are for non-negative integral exponents, integral 
 exponents, and floating-point exponents respectively.
I wonder whether that's an illustration of the power or of the failure of function overloading. (Seriously.)
I'm not sure either. I don't speak Haskell, but my guess is that ^ and ^^ were meant to cut out the confusion that would happen if Word32 ^ Word32 (what weird naming conventions Haskell has!) returned an integer type but Int32 ^ Int32 returned a floating point type. But why it needs yet another for floating-point exponents, I don't know. Maybe Haskell supports only IFTI rather than true function overloading.
It's essentially because Haskell has separate type classes (kiiiinda like D interfaces... I won't go into that topic) for integers, fractional numbers, and floating-point numbers. In D the types of those three operators could be something like: anyinteger ^(anyinteger base, anyinteger exponent); anyfractional ^^(anyfractional base, anyinteger exponent); anyfloating **(anyfloating base, anyfloating exponent); A noteworthy fractional is the Rational type, a ratio of two integral values. Note that 0.5 is a valid Rational: it's 1/2. Note, still, that 0.5 ** 0.5 is no longer a valid Rational: it's the square root of 1/2. This is why ^^ is separate: fractionals can be safely raised to integer exponents, but if you take a fractional and raise it to a fractional power, you might not get a fractional back.
Nov 08 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Matti Niemenmaa wrote:
<snip>
 It's essentially because Haskell has separate type classes (kiiiinda 
 like D interfaces... I won't go into that topic) for integers, 
 fractional numbers, and floating-point numbers. In D the types of those 
 three operators could be something like:
 
 anyinteger     ^(anyinteger    base, anyinteger  exponent);
 anyfractional ^^(anyfractional base, anyinteger  exponent);
 anyfloating   **(anyfloating   base, anyfloating exponent);
<snip> You've merely expanded on what I'd already made out - it doesn't explain why these generic functions can't share the same name. Is it because Haskell doesn't support function overloading as D does, or for some other reason? Stewart.
Nov 08 2009
parent Matti Niemenmaa <see_signature for.real.address> writes:
Stewart Gordon wrote:
 Matti Niemenmaa wrote:
 <snip>
 It's essentially because Haskell has separate type classes (kiiiinda 
 like D interfaces... I won't go into that topic) for integers, 
 fractional numbers, and floating-point numbers. In D the types of 
 those three operators could be something like:

 anyinteger     ^(anyinteger    base, anyinteger  exponent);
 anyfractional ^^(anyfractional base, anyinteger  exponent);
 anyfloating   **(anyfloating   base, anyfloating exponent);
<snip> You've merely expanded on what I'd already made out - it doesn't explain why these generic functions can't share the same name. Is it because Haskell doesn't support function overloading as D does, or for some other reason?
The former. Haskell does function overloading via type classes. I think that the reason why these functions can't have the same name is that they should all have a single, well-defined type and value. If they're all called 'pow', what is the type of pow? It can't have all three types at once, that makes no sense. And what happens if I give pow to a higher-order function: which one does it end up calling? You'd need some kind of notation to disambiguate. The developers of Haskell evidently opted to simply force differently-typed values to have different names, instead of being able to give them all the same name but then having to qualify which one you mean whenever you use it. That'd pretty much amount to them having different names anyway, I think. Just to show that this quality of Haskell isn't very limiting in practice, a somewhat tangential explanation of the way these exponentiation functions are overloaded follows. The types of these functions in Haskell are (read '::' as 'has type', the type after the last '->' as the return value and the others as the parameters): (^) :: (Num a, Integral b) => a -> b -> a (^^) :: (Fractional a, Integral b) => a -> b -> a (**) :: (Floating a) => a -> a -> a The part before the '=>' is the class context, restricting the type variables 'a' and 'b'. 'a' and 'b' can be any type at all, as long as they satisfy the constraints. For instance, for (^), the base can be of any numeric type, but the exponent must be integral, and the result is of the same numeric type as the base. So when you're actually using the function, you might be using it under any of the following types: (^) :: Integer -> Integer -> Integer (^) :: Float -> Integer -> Float (^) :: Double -> Int8 -> Double As you can see, the functions are already overloaded, in a sense. What Haskell does not support is 'overloading the implementation' the way derivatives of C++ (or whatever language first came up with this) do: a function cannot have different implementations for different types. Instead, a type class defines certain methods that each type that is an instance of it must implement. For example, (^) could be defined in terms of (==), (*), and (-), like so: base ^ pow = if pow == 0 then 1 else base * (base ^ (pow-1)) (*) and (-) are methods of the Num class, and (==) belongs to a superclass of Num, so we can infer the type of this as: (^) :: (Num a, Num b) => a -> b -> a (The standard-library one restricts b to Integral, because this kind of definition is obviously valid only for integer exponents.) We now have a generic implementation of (^) that works for any two number types. What we can't do is say that it should do something different for certain types: its definition shows that it depends only on the methods (==), (*), and (-), so if we want to change the behaviour of (^) we can do so only by changing their behaviour. This is doable only by changing the Num instance involved, which can only be done by changing the types in question. The only things that can change their behaviour directly depending on the types involved are class methods, which are defined separately for each type. For instance, (-) is defined for Integers as bignum subtraction and (-) for Floats is some kind of built-in operation which eventually compiles to an fsub on x86. In fact, (**) is a method of the Floating class, and thus has a separate implementation for all floating-point types. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
Nov 08 2009
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Nov 07 2009
next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:

 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
Nov 07 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Robert Jacques (sandford jhu.edu)'s article
 On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:
 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
On a more serious note, I'm starting to think that Phobos needs a specific convenience function for sum, not because reduce!"a + b" is ugly (it isn't) or too much typing (it isn't) but because reduce!"a + b" doesn't work on zero-length ranges. Obviously, the sum of a zero-length range is zero, but reduce is too general to know this. This bit me a few times in some code I was debugging last week. Rather than inserting extra checks or passing an explicit start value in (which requires you to remember the element type of your range; is it an int or a float?), I simply handwrote a sum function and replaced all my reduce!"a + b" with sum.
Nov 07 2009
next sibling parent reply =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
dsimcha wrote:
 == Quote from Robert Jacques (sandford jhu.edu)'s article
 On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:
 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
On a more serious note, I'm starting to think that Phobos needs a specific convenience function for sum, not because reduce!"a + b" is ugly (it isn't) or too much typing (it isn't) but because reduce!"a + b" doesn't work on zero-length ranges. Obviously, the sum of a zero-length range is zero, but reduce is too general to know this. This bit me a few times in some code I was debugging last week. Rather than inserting extra checks or passing an explicit start value in (which requires you to remember the element type of your range; is it an int or a float?), I simply handwrote a sum function and replaced all my reduce!"a + b" with sum.
I am all in favor of adding convenience functions sum and product to phobos. I use them both often enough.
Nov 07 2009
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, Nov 7, 2009 at 17:33, Pelle M=E5nsson <pelle.mansson gmail.com> wro=
te:

 I am all in favor of adding convenience functions sum and product to
 phobos. I use them both often enough.
vote++ And also min (on a range), max (on a range). Those are simple one-liners, though they can create some name-shadowing problems and are dubious with empty ranges. ElementType!R min(R)(R range) { enforce(!range.empty, "Don't use min on an empty range."); return reduce!(std.algorithm.min)(ElementType!R.max, range); } Maybe R doesn't have elements with a .max property, but then the same remar= k can be used on sum/product (0 or 1 are not necessarily the neutral elements for + and * on your struct/class). For specific structures, use your own su= m function. Some other languages also have and( on a boolean range) and or( on a boolea= n range), though I never use them. They are slightly different from reduce!"a&&b"(range) as they can exit early on a 'false' or 'true'. Has anyone ever used this? Philippe
Nov 08 2009
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 11:26:36 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Robert Jacques (sandford jhu.edu)'s article
 On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:
 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses
**)
 It's primarily about syntax sugar: pow() is so ugly. In practice, the
 most important case is squaring, which is an extremely common  
operation.
 pow(xxx,2) is horribly ugly for something so fundamental. It's so  
ugly
 that noone uses it: you always change it to xxx * xxx. But then, xxx
 gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly
ugly
 for something so fundamental. It's so ugly that noone uses it: you
 always change it to n*(n+1)/2. But then, n gets evaluated twice.

 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
On a more serious note, I'm starting to think that Phobos needs a specific convenience function for sum, not because reduce!"a + b" is ugly (it isn't) or too much typing (it isn't) but because reduce!"a + b" doesn't work on zero-length ranges. Obviously, the sum of a zero-length range is zero, but reduce is too general to know this. This bit me a few times in some code I was debugging last week. Rather than inserting extra checks or passing an explicit start value in (which requires you to remember the element type of your range; is it an int or a float?), I simply handwrote a sum function and replaced all my reduce!"a + b" with sum.
I'd recommend rolling that into a basic statistics struct containing common single pass metrics: i.e. sum, mean, variance, min, max, etc. P.S. Don't forget to vote for the patches in bugzilla.
Nov 07 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing 
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Nov 07 2009
parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing  
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Yes, but reduce(mean, std)(range) doesn't work. Even reduce(count) would require the range to be mapped. Besides, in my use case I need lazy evaluation, and I'd much rather add elements to a statistics struct, than write a range wrapper.
Nov 07 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Robert Jacques wrote:
 On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing 
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Yes, but reduce(mean, std)(range) doesn't work.
From std.algorithm's doc: // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); // Compute average and standard deviation from the above auto avg = r.field[0] / a.length; auto stdev = sqrt(r.field[1] / a.length - avg * avg); I'm not saying there's no need for a more specialized library, just that I purposely designed reduce to be no slouch either.
 Even reduce(count) would 
 require the range to be mapped.
(This I don't get.)
 Besides, in my use case I need lazy 
 evaluation, and I'd much rather add elements to a statistics struct, 
 than write a range wrapper.
Well if you go for surgery on an existing struct then the opportunity for reuse is diminished. Andrei
Nov 07 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Robert Jacques wrote:
 On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Yes, but reduce(mean, std)(range) doesn't work.
From std.algorithm's doc: // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); // Compute average and standard deviation from the above auto avg = r.field[0] / a.length; auto stdev = sqrt(r.field[1] / a.length - avg * avg); I'm not saying there's no need for a more specialized library, just that I purposely designed reduce to be no slouch either.
Don't get me wrong, I love reduce and it's definitely the right tool for some jobs. It's just that computing standard deviations isn't one of them. Finding the sum of the squares explicitly is an absolutely **horrible** way to find the standard deviation because it's numerically unstable. What if you have a few billion numbers being read in lazily from a file and you want to find the standard deviation of them? Heck, summing explicitly isn't even a very good way to find the mean. I'm sure you could implement a proper algorithm for this using reduce, but it would be really awkward. IMHO reduce's place is as a convenience for simple things like finding the max and min of a range. Once you're trying to shoehorn something into reduce that doesn't fit nicely, it's time to give up using reduce and just write a "real" function.
Nov 07 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Robert Jacques wrote:
 On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Yes, but reduce(mean, std)(range) doesn't work.
From std.algorithm's doc: // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); // Compute average and standard deviation from the above auto avg = r.field[0] / a.length; auto stdev = sqrt(r.field[1] / a.length - avg * avg); I'm not saying there's no need for a more specialized library, just that I purposely designed reduce to be no slouch either.
Don't get me wrong, I love reduce and it's definitely the right tool for some jobs. It's just that computing standard deviations isn't one of them. Finding the sum of the squares explicitly is an absolutely **horrible** way to find the standard deviation because it's numerically unstable. What if you have a few billion numbers being read in lazily from a file and you want to find the standard deviation of them? Heck, summing explicitly isn't even a very good way to find the mean. I'm sure you could implement a proper algorithm for this using reduce, but it would be really awkward. IMHO reduce's place is as a convenience for simple things like finding the max and min of a range. Once you're trying to shoehorn something into reduce that doesn't fit nicely, it's time to give up using reduce and just write a "real" function.
I agree. Andrei
Nov 07 2009
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 16:53:01 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Robert Jacques wrote:
 On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:

 Robert Jacques wrote:
 I'd recommend rolling that into a basic statistics struct containing  
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
Well the problem is that if you want to compute several one-pass statistics in one pass, you'd have to invent means to combine these functions. That ability is already present in reduce, e.g. reduce(min, max)(range) yields a pair containing the min and the max element after exactly one pass through range. Andrei
Yes, but reduce(mean, std)(range) doesn't work.
From std.algorithm's doc: // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); // Compute average and standard deviation from the above auto avg = r.field[0] / a.length; auto stdev = sqrt(r.field[1] / a.length - avg * avg); I'm not saying there's no need for a more specialized library, just that I purposely designed reduce to be no slouch either.
 Even reduce(count) would require the range to be mapped.
(This I don't get.)
 Besides, in my use case I need lazy evaluation, and I'd much rather add  
 elements to a statistics struct, than write a range wrapper.
Well if you go for surgery on an existing struct then the opportunity for reuse is diminished. Andrei
Thanks. BTW the behavior of a tuple as input to a multiple function reduce, although in the example, doesn't seem to be in the doc text.
Nov 07 2009
prev sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Robert Jacques (sandford jhu.edu)'s article
 I'd recommend rolling that into a basic statistics struct containing
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
I've been wondering for a while if something like this is general enough for non-statisticians and a good candidate for Phobos: http://svn.dsource.org/projects/dstats/docs/summary.html Good? Overkill? Too niche?
Nov 07 2009
next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 14:22:01 -0500, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Robert Jacques (sandford jhu.edu)'s article
 I'd recommend rolling that into a basic statistics struct containing
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
I've been wondering for a while if something like this is general enough for non-statisticians and a good candidate for Phobos: http://svn.dsource.org/projects/dstats/docs/summary.html Good? Overkill? Too niche?
Looks good.
Nov 07 2009
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, Nov 7, 2009 at 20:22, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Robert Jacques (sandford jhu.edu)'s article
 I'd recommend rolling that into a basic statistics struct containing
 common single pass metrics: i.e. sum, mean, variance, min, max, etc.
I've been wondering for a while if something like this is general enough for non-statisticians and a good candidate for Phobos: http://svn.dsource.org/projects/dstats/docs/summary.html Good? Overkill? Too niche?
Oh nice. Though I'll probably never use dstats in its globality, I'll most certainly use this summary module. Having a small std.stats module inserted into phobos doesn't strike me as overkill or too niche, but maybe I'm biased. I'm sure everyone here use less than a dozen modules on most projects. I mean, I never do sockets, xml, GUI, ... But I intensively use std.functional, algorithm, traits, range, typecons, typetuple, array, ...
Nov 08 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Robert Jacques (sandford jhu.edu)'s article
 On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:
 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
On a more serious note, I'm starting to think that Phobos needs a specific convenience function for sum, not because reduce!"a + b" is ugly (it isn't) or too much typing (it isn't) but because reduce!"a + b" doesn't work on zero-length ranges. Obviously, the sum of a zero-length range is zero, but reduce is too general to know this. This bit me a few times in some code I was debugging last week. Rather than inserting extra checks or passing an explicit start value in (which requires you to remember the element type of your range; is it an int or a float?), I simply handwrote a sum function and replaced all my reduce!"a + b" with sum.
Just in case it helps, the two-arguments version of reduce is meant exactly to make it work with an empty array and seed the accumulation. Namely, reduce!"a+b"(range) throws on an empty range, but reduce!"a+b"(0.0, range) returns 0.0 on an empty range. Andrei
Nov 07 2009
prev sibling parent KennyTM~ <kennytm gmail.com> writes:
On Nov 8, 09 00:15, Robert Jacques wrote:
 On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:

 On Nov 7, 09 18:43, Don wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an
 exponentiation. A couple of people had requested that I make a post
 to the ng so they'd know when it happens. Here it is.

 This is opPow(), x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to xxx * xxx. But then, xxx gets evaluated twice.
Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In practice, the most important case is the sum from 1 to n, which is an extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly for something so fundamental. It's so ugly that noone uses it: you always change it to n*(n+1)/2. But then, n gets evaluated twice.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used **
 because it had such a limited character set, but it's not really a
 natural choice; the more mathematically-oriented languages use ^.
 Obviously C-family languages don't have that possibility.
Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;
Or pure nothrow T ²(T)(T x) { return x*x; } alias sqrt √; :p (OK ²(xxx) is still odd.)
Nov 07 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
KennyTM~ wrote:
 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's 
 primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In 
 practice, the most important case is the sum from 1 to n, which is an 
 extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly ugly 
 for something so fundamental. It's so ugly that noone uses it: you 
 always change it to n*(n+1)/2. But then, n gets evaluated twice.
As amply illustrated, one can make this argument pro and con about any builtin operator. The waterfront real estate of builtin operators is extremely limited, so we need to be very parsimonious in allocating it. Candidates for builtin operators need to have a very high bar. The question is, does ^^ clear that bar or not?
Nov 07 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 KennyTM~ wrote:
 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's 
 primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In 
 practice, the most important case is the sum from 1 to n, which is an 
 extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly 
 ugly for something so fundamental. It's so ugly that noone uses it: 
 you always change it to n*(n+1)/2. But then, n gets evaluated twice.
As amply illustrated, one can make this argument pro and con about any builtin operator. The waterfront real estate of builtin operators is extremely limited, so we need to be very parsimonious in allocating it. Candidates for builtin operators need to have a very high bar. The question is, does ^^ clear that bar or not?
In order for everyone to air an informed opinion, a related question is: will loop fusion be allowed with function calls? Loop fusion currently only works with operators, and adding ^^ would allow: a[] = b[] ^^ 3; But with pow you can't do that: a[] = pow(b[], 3); Andrei P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for automatic loop fusion that would tilt my opinion in disfavor of ^^, and if not, it would tilt my opinion in favor of ^^.
Nov 07 2009
next sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Andrei Alexandrescu wrote:
 Walter Bright wrote:
 KennyTM~ wrote:
 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's
 primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In
 practice, the most important case is the sum from 1 to n, which is an
 extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly
 ugly for something so fundamental. It's so ugly that noone uses it:
 you always change it to n*(n+1)/2. But then, n gets evaluated twice.
As amply illustrated, one can make this argument pro and con about any builtin operator. The waterfront real estate of builtin operators is extremely limited, so we need to be very parsimonious in allocating it. Candidates for builtin operators need to have a very high bar. The question is, does ^^ clear that bar or not?
In order for everyone to air an informed opinion, a related question is: will loop fusion be allowed with function calls? Loop fusion currently only works with operators, and adding ^^ would allow: a[] = b[] ^^ 3; But with pow you can't do that: a[] = pow(b[], 3); Andrei P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for automatic loop fusion that would tilt my opinion in disfavor of ^^, and if not, it would tilt my opinion in favor of ^^.
Does ^^ really even need to be a builtin operator to be overloadable? I remember a discussion where we considered adding abstract operators that have no inherent meaning in the language (not builtins), but are overloadable to allow better exploitation of infix notation. Things like (+), (*), (%), (&), [+], [*], [%], and so on.
Nov 07 2009
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 In order for everyone to air an informed opinion, a related question is: 
 will loop fusion be allowed with function calls?
 
 Loop fusion currently only works with operators, and adding ^^ would allow:
 
 a[] = b[] ^^ 3;
 
 But with pow you can't do that:
 
 a[] = pow(b[], 3);
 
 
 Andrei
 
 P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for 
 automatic loop fusion that would tilt my opinion in disfavor of ^^, and 
 if not, it would tilt my opinion in favor of ^^.
I don't think this is a valid argument for making pow() an operator, because what about sin()? cos()? It's all the same issue, and they all can't be operators.
Nov 07 2009
next sibling parent Don <nospam nospam.com> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 In order for everyone to air an informed opinion, a related question 
 is: will loop fusion be allowed with function calls?

 Loop fusion currently only works with operators, and adding ^^ would 
 allow:

 a[] = b[] ^^ 3;

 But with pow you can't do that:

 a[] = pow(b[], 3);


 Andrei

 P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for 
 automatic loop fusion that would tilt my opinion in disfavor of ^^, 
 and if not, it would tilt my opinion in favor of ^^.
I don't think this is a valid argument for making pow() an operator, because what about sin()? cos()? It's all the same issue, and they all can't be operators.
It's another case where pow(x, 2) is not the same as x ^^ 2. The argument for excluding exponentiation is largely, "pow does the same thing, without introducing an operator".
Nov 07 2009
prev sibling parent reply Tim Matthews <tim.matthews7 gmail.com> writes:
Walter Bright wrote:
 Andrei Alexandrescu wrote:
 In order for everyone to air an informed opinion, a related question 
 is: will loop fusion be allowed with function calls?

 Loop fusion currently only works with operators, and adding ^^ would 
 allow:

 a[] = b[] ^^ 3;

 But with pow you can't do that:

 a[] = pow(b[], 3);


 Andrei

 P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for 
 automatic loop fusion that would tilt my opinion in disfavor of ^^, 
 and if not, it would tilt my opinion in favor of ^^.
I don't think this is a valid argument for making pow() an operator, because what about sin()? cos()? It's all the same issue, and they all can't be operators.
Exponentiation, like addition, multiplication etc.. can be used multiple times in an expression at the same scope: a + b + c a * b * c a ^^ b ^^ c xor, sin, cos are only binary & unary operations. I think that is a good enough argument for which deserves operator over long function name but unlike the others, exponentiation is right associative so this should mean the same as: a ^^ (b ^^ c) This may also reduce the likely hood of bugs due to mathematical formulas being expressed incorrectly. It is far too easy to accidentally write: a ^^ b ^^ c as pow(pow(a,b),c) This one operator would really help D be accepted into the mathematical world.
Nov 08 2009
parent reply Nick B <"nick_NOSPAM_.barbalich" gmail.com> writes:
What is the definition that this community is succeeding / making progress ?

I would like to propose there is _only_ one.  That the community is 
growing from year to year.

 From ten years ago when Walter, started the D project it certainly has 
grown, but compared to one year ago, has it grown or shrunk ?  Without 
any hard data there is no way to know.

I propose a brief email survey to gather of the size of the community, 
repeated at yearly intervals.

Proposed questions:

Name:
Alternative name (handle:)
Number of years using D:
Framework: Phobos ; Tango, Both; None; & Other


Comments ?


regards
Nick B
Nov 08 2009
next sibling parent Travis Boucher <boucher.travis gmail.com> writes:
Nick B wrote:
 What is the definition that this community is succeeding / making 
 progress ?
 
 I would like to propose there is _only_ one.  That the community is 
 growing from year to year.
 
  From ten years ago when Walter, started the D project it certainly has 
 grown, but compared to one year ago, has it grown or shrunk ?  Without 
 any hard data there is no way to know.
 
 I propose a brief email survey to gather of the size of the community, 
 repeated at yearly intervals.
 
 Proposed questions:
 
 Name:
 Alternative name (handle:)
 Number of years using D:
 Framework: Phobos ; Tango, Both; None; & Other
 
 
 Comments ?
 
 
 regards
 Nick B
An Email Survey is the quickest way to turn me into a silent NG prowler with a new email address. If you want to do a survey, post it in the NG and have people optionally go to a site to fill it out. Even then, it won't give accurate results. I'd suggest that a better metric of community growth is community involvement in open source projects and discussion (eg. dsource stats and NG stats).
Nov 08 2009
prev sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
Nick B, el  9 de noviembre a las 15:19 me escribiste:
 What is the definition that this community is succeeding / making progress ?
 
 I would like to propose there is _only_ one.  That the community is
 growing from year to year.
 
 From ten years ago when Walter, started the D project it certainly
 has grown, but compared to one year ago, has it grown or shrunk ?
 Without any hard data there is no way to know.
 
 I propose a brief email survey to gather of the size of the
 community, repeated at yearly intervals.
 
 Proposed questions:
 
 Name:
 Alternative name (handle:)
 Number of years using D:
 Framework: Phobos ; Tango, Both; None; & Other
 
 
 Comments ?
Git does a very nice and useful survey each year: http://git.or.cz/gitwiki/GitSurvey2009 An DVCS is not the same as a language, but it can be taken as a base. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- De las generaciones venideras espero, nada más, que vengan. -- Ricardo Vaporeso
Nov 08 2009
next sibling parent Nick B <"nick_NOSPAM_.barbalich" gmail.com> writes:
Leandro Lucarella wrote:
 Nick B, el  9 de noviembre a las 15:19 me escribiste:
 What is the definition that this community is succeeding / making progress ?
 
 Git does a very nice and useful survey each year:
 http://git.or.cz/gitwiki/GitSurvey2009
 
 An DVCS is not the same as a language, but it can be taken as a base.
 
thanks. This is a excellent example ! Nick B
Nov 08 2009
prev sibling parent Nick B <"nick_NOSPAM_.barbalich" gmail.com> writes:
Leandro Lucarella wrote:
 Nick B, el  9 de noviembre a las 15:19 me escribiste:
 What is the definition that this community is succeeding / making progress ?

 I would like to propose there is _only_ one.  That the community is
 growing from year to year.

 From ten years ago when Walter, started the D project it certainly
 has grown, but compared to one year ago, has it grown or shrunk ?
 Without any hard data there is no way to know.

 I propose a brief email survey to gather of the size of the
 community, repeated at yearly intervals.

 Proposed questions:

 Name:
 Alternative name (handle:)
 Number of years using D:
 Framework: Phobos ; Tango, Both; None; & Other


 Comments ?
Git does a very nice and useful survey each year: http://git.or.cz/gitwiki/GitSurvey2009 An DVCS is not the same as a language, but it can be taken as a base.
Hi Leandro, thank you for this high quality example. I have had very little response, (and one response privately), so I can only assume that almost no one sees any value in this. I thought Walter might although. So I will do nothing for now, and may raise this next year. cheers Nick B ps perhaps this community need a marketing director.
Nov 10 2009
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 07 Nov 2009 13:37:33 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Walter Bright wrote:
 KennyTM~ wrote:
 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's  
 primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In  
 practice, the most important case is the sum from 1 to n, which is an  
 extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly  
 ugly for something so fundamental. It's so ugly that noone uses it:  
 you always change it to n*(n+1)/2. But then, n gets evaluated twice.
As amply illustrated, one can make this argument pro and con about any builtin operator. The waterfront real estate of builtin operators is extremely limited, so we need to be very parsimonious in allocating it. Candidates for builtin operators need to have a very high bar. The question is, does ^^ clear that bar or not?
In order for everyone to air an informed opinion, a related question is: will loop fusion be allowed with function calls? Loop fusion currently only works with operators, and adding ^^ would allow: a[] = b[] ^^ 3; But with pow you can't do that: a[] = pow(b[], 3); Andrei P.S. FWIW, I'm ambivalent on the issue; if functions were allowed for automatic loop fusion that would tilt my opinion in disfavor of ^^, and if not, it would tilt my opinion in favor of ^^.
Actually, if you look at Matlab, a[] = b[] ^^ 3; is well defined. Also, given real foo(real r) { return r*r; } providing syntactic sugar for a[] = foo(b[], 3); => a[] = map!foo(b[],3); might be nice.
Nov 07 2009
prev sibling parent reply "Phil Deets" <pjdeets2 gmail.com> writes:
On Sat, 07 Nov 2009 13:37:33 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:
 In order for everyone to air an informed opinion, a related question is:  
 will loop fusion be allowed with function calls?

 Loop fusion currently only works with operators, and adding ^^ would  
 allow:

 a[] = b[] ^^ 3;

 But with pow you can't do that:

 a[] = pow(b[], 3);


 Andrei
If a function is marked pure, I don't see any reason why this would be a bad idea.
Nov 07 2009
parent "Phil Deets" <pjdeets2 gmail.com> writes:
On Sat, 07 Nov 2009 21:31:46 -0500, Phil Deets <pjdeets2 gmail.com> wrote:

 On Sat, 07 Nov 2009 13:37:33 -0500, Andrei Alexandrescu  
 <SeeWebsiteForEmail erdani.org> wrote:
 In order for everyone to air an informed opinion, a related question  
 is: will loop fusion be allowed with function calls?

 Loop fusion currently only works with operators, and adding ^^ would  
 allow:

 a[] = b[] ^^ 3;

 But with pow you can't do that:

 a[] = pow(b[], 3);


 Andrei
If a function is marked pure, I don't see any reason why this would be a bad idea.
Make that pure and nothrow (and possibly safe).
Nov 07 2009
prev sibling parent Don <nospam nospam.com> writes:
Walter Bright wrote:
 KennyTM~ wrote:
 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's 
 primarily about syntax sugar: reduce!("a+b")(range) is so ugly. In 
 practice, the most important case is the sum from 1 to n, which is an 
 extremely common operation. reduce!("a+b")(iota(1,n+1)) is horribly 
 ugly for something so fundamental. It's so ugly that noone uses it: 
 you always change it to n*(n+1)/2. But then, n gets evaluated twice.
As amply illustrated, one can make this argument pro and con about any builtin operator. The waterfront real estate of builtin operators is extremely limited, so we need to be very parsimonious in allocating it. Candidates for builtin operators need to have a very high bar. The question is, does ^^ clear that bar or not?
Yes, that's exactly the question. From an old post by Bill Baxter, here's a list of languages with an exponentiation operator: derivatives), Haskell (for non-negative integer exponents), and most computer algebra systems Haskell (for floating-point exponents), Turing None of the languages derived from C and Pascal include exponentiation. (I suspect that if it had been included in C, there would be very few languages without it: since Algol and Fortran both had it). Note that D currently has <>, <>=, !<>, !<>=, !>=, !<=, !>, !<, which would have to be lower down the list than exponentiation. As one of the very few users who actually uses them, I'd happily sacrifice them in exchange for exponentiation. And BTW, there is another issue with pow(), relating to implicit conversion. Given an int x, x * x is also an int. But pow(x, 2) is a double, so they are not at all equivalent. (and pow() definitely needs to return float for general exponents). The recently introduced integer range tracking for implicit conversions could fix this nicely.
Nov 07 2009
prev sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Sat, Nov 7, 2009 at 2:43 AM, Don <nospam nospam.com> wrote:
 Walter Bright wrote:
 Don wrote:
 A little while ago I said I'd create a patch for ^^ as an exponentiatio=
n.
 A couple of people had requested that I make a post to the ng so they'd=
know
 when it happens. Here it is.

 This is opPow(), =A0x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3D3481
I don't understand the rationale for an exponentiation operator. It isn'=
t
 optimization, because pow() could become an intrinsic that the compiler
 knows about. pow() is well known, ^^ isn't. (Fortran uses **)
Yes, pow() is a well-known annoyance in languages that don't have an exponentiation operator. :-)
 It's primarily about syntax sugar: pow() is so ugly. In practice, the mos=
t
 important case is squaring, which is an extremely common operation.
 pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly th=
at
 noone uses it: you always change it to xxx * xxx. But then, xxx gets
 evaluated twice.
xxx also has to be typed twice. Cubes also appear fairly often.
 Yes, ^^ hasn't been used for exponentiation before. Fortran used ** becau=
se
 it had such a limited character set, but it's not really a natural choice=
;
 the more mathematically-oriented languages use ^. Obviously C-family
 languages don't have that possibility.
I think ^^ is a fine choice. This is great for folks who do a lot of numerical stuff. --bb
Nov 08 2009
prev sibling parent reply Mo Chen <sth4nth gmail.com> writes:
Suppose we have a matrix library, I'd like to have two product operators,
one is for matrix product, the other is for element wise product, just like
what we do in matlab (A*B and A.*B). I'd like to save ** to that scenario.
Btw I'm no Fortran user. ^^ is fine by me.

On Sat, Nov 7, 2009 at 5:56 PM, Walter Bright <newshound1 digitalmars.com>wrote:

 Don wrote:

 A little while ago I said I'd create a patch for ^^ as an exponentiation.
 A couple of people had requested that I make a post to the ng so they'd know
 when it happens. Here it is.

 This is opPow(),  x ^^ y

 http://d.puremagic.com/issues/show_bug.cgi?id=3481
I don't understand the rationale for an exponentiation operator. It isn't optimization, because pow() could become an intrinsic that the compiler knows about. pow() is well known, ^^ isn't. (Fortran uses **)
Nov 07 2009
parent Don <nospam nospam.com> writes:
Mo Chen wrote:
 Suppose we have a matrix library, I'd like to have two product 
 operators, one is for matrix product, the other is for element wise 
 product, just like what we do in matlab (A*B and A.*B). I'd like to save 
 ** to that scenario. Btw I'm no Fortran user. ^^ is fine by me.
The D forms are A*B for matrix product, A[]*B[] for element-wise product. <g>.
Nov 07 2009