digitalmars.D - opPow, opDollar
- Don (15/15) Nov 07 2009 A little while ago I said I'd create a patch for ^^ as an
- Walter Bright (4/11) Nov 07 2009 I don't understand the rationale for an exponentiation operator. It
- Lars T. Kyllingstad (15/26) Nov 07 2009 AWESOME! Thanks a lot, Don! I've been hoping for this since I started
- Don (10/22) Nov 07 2009 It's primarily about syntax sugar: pow() is so ugly. In practice, the
- Mike James (2/3) Nov 07 2009 And BASIC ;-)
- Matti Niemenmaa (4/8) Nov 07 2009 Haskell has three exponentiation operators in the standard library: ^,
- Andrei Alexandrescu (4/13) Nov 07 2009 I wonder whether that's an illustration of the power or of the failure
- Stewart Gordon (8/21) Nov 07 2009 I'm not sure either. I don't speak Haskell, but my guess is that ^ and
- Matti Niemenmaa (14/30) Nov 08 2009 It's essentially because Haskell has separate type classes (kiiiinda
-
Stewart Gordon
(8/16)
Nov 08 2009
- Matti Niemenmaa (59/75) Nov 08 2009 The former. Haskell does function overloading via type classes.
- KennyTM~ (7/29) Nov 07 2009 Nice. Meanwhile, I'd like an opSum() operator (∑ range) as well. It's
- Robert Jacques (3/35) Nov 07 2009 Well, since D supports unicode, you can always define: alias
- dsimcha (10/48) Nov 07 2009 On a more serious note, I'm starting to think that Phobos needs a specif...
- =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= (3/48) Nov 07 2009 I am all in favor of adding convenience functions sum and product to
- Philippe Sigaud (22/24) Nov 08 2009 vote++
- Robert Jacques (4/64) Nov 07 2009 I'd recommend rolling that into a basic statistics struct containing
- Andrei Alexandrescu (7/9) Nov 07 2009 Well the problem is that if you want to compute several one-pass
- Robert Jacques (6/15) Nov 07 2009 Yes, but reduce(mean, std)(range) doesn't work. Even reduce(count) would...
- Andrei Alexandrescu (13/34) Nov 07 2009 From std.algorithm's doc:
- dsimcha (13/38) Nov 07 2009 Don't get me wrong, I love reduce and it's definitely the right tool for...
- Andrei Alexandrescu (3/41) Nov 07 2009 I agree.
- Robert Jacques (4/35) Nov 07 2009 Thanks. BTW the behavior of a tuple as input to a multiple function
- dsimcha (5/7) Nov 07 2009 I've been wondering for a while if something like this is general enough...
- Robert Jacques (2/10) Nov 07 2009 Looks good.
- Philippe Sigaud (8/16) Nov 08 2009 Oh nice. Though I'll probably never use dstats in its globality, I'll mo...
- Andrei Alexandrescu (6/51) Nov 07 2009 Just in case it helps, the two-arguments version of reduce is meant
- KennyTM~ (6/44) Nov 07 2009 Or
- Walter Bright (6/12) Nov 07 2009 As amply illustrated, one can make this argument pro and con about any
- Andrei Alexandrescu (11/25) Nov 07 2009 In order for everyone to air an informed opinion, a related question is:...
- Chad J (6/39) Nov 07 2009 Does ^^ really even need to be a builtin operator to be overloadable?
- Walter Bright (4/21) Nov 07 2009 I don't think this is a valid argument for making pow() an operator,
- Don (4/28) Nov 07 2009 It's another case where pow(x, 2) is not the same as x ^^ 2.
- Tim Matthews (19/43) Nov 08 2009 Exponentiation, like addition, multiplication etc.. can be used multiple...
- Nick B (16/16) Nov 08 2009 What is the definition that this community is succeeding / making progre...
- Travis Boucher (8/34) Nov 08 2009 An Email Survey is the quickest way to turn me into a silent NG prowler
- Leandro Lucarella (11/32) Nov 08 2009 Git does a very nice and useful survey each year:
- Robert Jacques (8/32) Nov 07 2009 Actually, if you look at Matlab, a[] = b[] ^^ 3; is well defined.
- Phil Deets (4/12) Nov 07 2009 If a function is marked pure, I don't see any reason why this would be a...
- Phil Deets (2/22) Nov 07 2009 Make that pure and nothrow (and possibly safe).
- Don (23/37) Nov 07 2009 Yes, that's exactly the question. From an old post by Bill Baxter,
- Bill Baxter (14/38) Nov 08 2009 know
- Mo Chen (5/17) Nov 07 2009 Suppose we have a matrix library, I'd like to have two product operators...
- Don (3/7) Nov 07 2009 The D forms are A*B for matrix product, A[]*B[] for element-wise produc...
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
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=3481I 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
Walter Bright wrote:Don wrote:AWESOME! Thanks a lot, Don! I've been hoping for this since I started using D. Walter Bright 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=3481I 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
Walter Bright wrote:Don wrote: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.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=3481I 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
the more mathematically-oriented languages use ^And BASIC ;-) -=mike=-
Nov 07 2009
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
Matti Niemenmaa wrote:Don wrote:I wonder whether that's an illustration of the power or of the failure of function overloading. (Seriously.) AndreiYes, ^^ 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
Andrei Alexandrescu wrote:Matti Niemenmaa wrote: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.Don wrote:I wonder whether that's an illustration of the power or of the failure of function overloading. (Seriously.)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
Stewart Gordon wrote:Andrei Alexandrescu wrote: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.Matti Niemenmaa wrote: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.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.)
Nov 08 2009
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
Stewart Gordon wrote:Matti Niemenmaa wrote: <snip>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) fiIt'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?
Nov 08 2009
On Nov 7, 09 18:43, Don wrote:Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:On Nov 7, 09 18:43, Don wrote:Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
== Quote from Robert Jacques (sandford jhu.edu)'s articleOn Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote: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.On Nov 7, 09 18:43, Don wrote:Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
dsimcha wrote:== Quote from Robert Jacques (sandford jhu.edu)'s articleI am all in favor of adding convenience functions sum and product to phobos. I use them both often enough.On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote: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.On Nov 7, 09 18:43, Don wrote:Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
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
On Sat, 07 Nov 2009 11:26:36 -0500, dsimcha <dsimcha yahoo.com> wrote:== Quote from Robert Jacques (sandford jhu.edu)'s articleI'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.On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote: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.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=3481I 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 usesoperation.It's primarily about syntax sugar: pow() is so ugly. In practice, the most important case is squaring, which is an extremely commonuglypow(xxx,2) is horribly ugly for something so fundamental. It's souglythat 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 horriblyfor 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.Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;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
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
On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Robert Jacques wrote: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.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
Robert Jacques wrote:On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.Robert Jacques wrote:Yes, but reduce(mean, std)(range) doesn't work.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. AndreiEven 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
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleRobert Jacques wrote: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.On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.Robert Jacques wrote:Yes, but reduce(mean, std)(range) doesn't work.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
dsimcha wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleI agree. AndreiRobert Jacques wrote: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.On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.Robert Jacques wrote:Yes, but reduce(mean, std)(range) doesn't work.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
On Sat, 07 Nov 2009 16:53:01 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Robert Jacques wrote: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.On Sat, 07 Nov 2009 12:56:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.Robert Jacques wrote:Yes, but reduce(mean, std)(range) doesn't work.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. AndreiEven 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
== Quote from Robert Jacques (sandford jhu.edu)'s articleI'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
On Sat, 07 Nov 2009 14:22:01 -0500, dsimcha <dsimcha yahoo.com> wrote:== Quote from Robert Jacques (sandford jhu.edu)'s articleLooks good.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
On Sat, Nov 7, 2009 at 20:22, dsimcha <dsimcha yahoo.com> wrote:== Quote from Robert Jacques (sandford jhu.edu)'s articleOh 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, ...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 08 2009
dsimcha wrote:== Quote from Robert Jacques (sandford jhu.edu)'s articleJust 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. AndreiOn Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote: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.On Nov 7, 09 18:43, Don wrote:Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
On Nov 8, 09 00:15, Robert Jacques wrote:On Sat, 07 Nov 2009 10:48:11 -0500, KennyTM~ <kennytm gmail.com> wrote:Or pure nothrow T ²(T)(T x) { return x*x; } alias sqrt √; :p (OK ²(xxx) is still odd.)On Nov 7, 09 18:43, Don wrote:Well, since D supports unicode, you can always define: alias reduce!("a+b") ∑;Walter Bright 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.Don wrote: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.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=3481I 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, ^^ 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
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
Walter Bright wrote:KennyTM~ 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 ^^.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
Andrei Alexandrescu wrote:Walter Bright wrote: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.KennyTM~ 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 ^^.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
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
Walter Bright wrote:Andrei Alexandrescu wrote: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".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
Walter Bright wrote:Andrei Alexandrescu wrote: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.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 08 2009
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
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 BAn 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
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
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
Leandro Lucarella wrote:Nick B, el 9 de noviembre a las 15:19 me escribiste: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.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.
Nov 10 2009
On Sat, 07 Nov 2009 13:37:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Walter Bright wrote: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.KennyTM~ 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 ^^.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
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); AndreiIf a function is marked pure, I don't see any reason why this would be a bad idea.
Nov 07 2009
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:Make that pure and nothrow (and possibly safe).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); AndreiIf a function is marked pure, I don't see any reason why this would be a bad idea.
Nov 07 2009
Walter Bright wrote:KennyTM~ wrote: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.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
On Sat, Nov 7, 2009 at 2:43 AM, Don <nospam nospam.com> wrote:Walter Bright wrote:n.Don wrote:A little while ago I said I'd create a patch for ^^ as an exponentiatio=knowA couple of people had requested that I make a post to the ng so they'd=twhen it happens. Here it is. This is opPow(), =A0x ^^ y http://d.puremagic.com/issues/show_bug.cgi?id=3D3481I don't understand the rationale for an exponentiation operator. It isn'=Yes, pow() is a well-known annoyance in languages that don't have an exponentiation operator. :-)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 mos=timportant case is squaring, which is an extremely common operation. pow(xxx,2) is horribly ugly for something so fundamental. It's so ugly th=atnoone 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=seit 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
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=3481I 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
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