digitalmars.D - Remove complex and imaginary types?
- Walter Bright (10/10) Jan 06 2008 The issue comes up now and then about why have complex and imaginary
- Oskar Linde (12/29) Jan 06 2008 Sounds like a good idea. Complex math is probably only used in a very
- davidl (9/32) Jan 07 2008 Oh, I didn't think of making i a struct...
- Robert Fraser (6/39) Jan 07 2008 The identifier "i" is rather frequently used, so I don;t think that's a
- renoX (5/46) Jan 07 2008 I think that you have the right suggestion here: what's wrong about the ...
- Bruce Adams (3/59) Jan 07 2008 Ignoring my previous post this rings a bell. I'm sure I've seen it in
- renoX (6/71) Jan 08 2008 Fortress has this:
- davidl (45/58) Jan 06 2008 So it's time for implicitCastFrom?
- Don Clugston (19/36) Jan 07 2008 There is also the advantage of standardisation, although I don't think i...
- John Reimer (10/33) Jan 07 2008 I agree with Don (how could I not? :D), although I really have little
- Georg Wrede (9/14) Jan 07 2008 I definitely don't pretend to understand any of that, but shouldn't it
- Bill Baxter (12/29) Jan 07 2008 The bottom line is that there really is no useful mathematics that can
- Don Clugston (12/41) Jan 08 2008 Right. In practice, I've found that you always convert ireal to real whe...
- BCS (12/21) Jan 08 2008 This is starting to touch on something I have been wanting: compile time...
- Robert Fraser (5/22) Jan 07 2008 I never use them in the style of code I write, so I personally wouldn't
- Bill Baxter (13/30) Jan 07 2008 I defer to Don on this one :-)
- Bruce Adams (22/48) Jan 07 2008 You must surely have noticed people using all kinds of weird and wonderf...
- Bill Baxter (16/70) Jan 07 2008 I think he's sensitive about the number-of-keywords argument people
- Walter Bright (2/5) Jan 07 2008 Python, C and Fortran.
- Bill Baxter (15/32) Jan 07 2008 While some way to write complex literals would be neat (because
- bearophile (26/40) Jan 07 2008 (5+0j)
- Georg Wrede (55/70) Jan 07 2008 Assuming the opponents of the D programming language are not reading
- Bill Baxter (17/53) Jan 07 2008 There is one thing we'd lose that hasn't been mentioned.
- John Reimer (29/53) Jan 07 2008 Wow... I've had the same feelings (without the experiences, however), bu...
- Sean Kelly (3/6) Jan 08 2008 Yes, it was well expressed and I feel much the same.
- Walter Bright (20/73) Jan 07 2008 I wouldn't remove it from the core language without having a complete
- Daniel919 (23/41) Jan 08 2008 What about a more general solution like
- Leandro Lucarella (13/42) Jan 08 2008 +1
- Jason House (2/8) Jan 08 2008 Any time a hack is needed, it's probably not the best solution. Somewhe...
- Christopher Wright (4/13) Jan 08 2008 I'd rather it were not. It reduces clarity, since the postfixes will be
- Sean Kelly (11/31) Jan 08 2008 I thought the standard library's inclusion in the language spec was one
- Georg Wrede (12/21) Jan 08 2008 Lisp? :-)
- Don Clugston (14/24) Jan 08 2008 There's a funny thing about this situation. Here's the background:
- Georg Wrede (9/41) Jan 08 2008 This should NEVER be an isolated goal. Rather, it should just be the
- Don Clugston (6/51) Jan 08 2008 I agree completely. It's the typical problem you get with any indirect m...
- Russell Lewis (4/9) Jan 09 2008 I wrote a programming language that used only 26 keywords: a,b,c,d...
- S. (5/20) Jan 08 2008 As a physicist who uses D for simulations, my answer is NO! Your origi...
- naryl (4/17) Jan 10 2008 "No issue left behind"
- bearophile (5/6) Jan 10 2008 Removing: -1. It's actually useful (I'd like to see more iteration const...
- naryl (13/29) Jan 10 2008 Let me quote Regan Heath:
- Yigal Chripun (21/66) Jan 11 2008 IMHO both foreach_reverse *and* foreach are ugly hacks and should be
- Russell Lewis (11/13) Jan 11 2008 I can see how we might choose to remove foreach_reverse (assuming that
- Pragma (6/30) Jan 11 2008 My $0.02:
- bearophile (4/5) Jan 11 2008 I'm waiting to see the first one bold enough to define and use monads wi...
- Matti Niemenmaa (9/17) Jan 11 2008 Ever since the language got the ability to use delegates as the foreach
- Oskar Linde (6/25) Jan 11 2008 And the only reason this isn't how its done is because dmd is unable to
- Robert Fraser (2/7) Jan 11 2008 +1. I really like this idea (if the inlining thing could be worked out).
- Reiner Pope (4/52) Jan 11 2008 Here's my version from a while back:
- Rioshin an'Harthen (8/59) Jan 12 2008 I agree - this suffix support should make it into the language. It would...
- renoX (12/65) Jan 12 2008 I like a lot all those proposal for adding suffix based literal, but I'm...
- Daniel919 (12/25) Jan 12 2008 I agree,
- Gilles G. (2/21) Jan 12 2008
- Janice Caron (6/8) Jan 12 2008 Why not the asterisk? Oh wait! - We already /have/ that functionality!
- renoX (10/23) Jan 12 2008 Because
- Daniel919 (40/49) Jan 12 2008 Here are some ideas how it would be even better than it could be with
- Ary Borenszweig (3/16) Jan 12 2008 But km, i, or whatever, must be at global scope, and then you couldn't
- Simen Kjaeraas (19/82) Jan 14 2008 =
- Pablo Ripolles (10/25) Jan 14 2008 Hello all,
- bearophile (4/6) Jan 14 2008 Predicting the future isn't easy. Maybe they will migrate to Python + Cy...
- Pablo Ripolles (3/11) Jan 14 2008 Indeed, predicting the future was not my intention. Yeah! that was an o...
- Don Clugston (26/59) Jan 14 2008 Yes, my comment wasn't really fair. Complex numbers are fundamental to
- Pablo Ripolles (2/69) Jan 14 2008
- Oskar Linde (6/23) Jan 15 2008 But since D doesn't guarantee inlining, I guess there would still be an
The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.
Jan 06 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the types built in are rendered irrelevant I see no reason not to take this opportunity to simplify the language. Regarding literals, I'd say this is would be an adequate replacement for the above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be a good thing. :) -- Oskar
Jan 06 2008
在 Mon, 07 Jan 2008 15:43:51 +0800,Oskar Linde <oskar.lindeREM OVEgmail.com> 写道:Walter Bright wrote:Oh, I didn't think of making i a struct... This would ban the use of i as a variable name. A lot of beginning tutorials use i as a variable name :) And sometimes I use it for convenience. And that would break a lot test purpose code. -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the types built in are rendered irrelevant I see no reason not to take this opportunity to simplify the language. Regarding literals, I'd say this is would be an adequate replacement for the above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be a good thing. :)
Jan 07 2008
Oskar Linde wrote:Walter Bright wrote:The identifier "i" is rather frequently used, so I don;t think that's a good idea. I'd prefer an opPostfix or something that allows literals with postfixes to be converted to different types. This would be especially nice for dealing with units, i.e.: writef("%s", toMiles(10km + 13ft));The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the types built in are rendered irrelevant I see no reason not to take this opportunity to simplify the language. Regarding literals, I'd say this is would be an adequate replacement for the above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be a good thing. :)
Jan 07 2008
Robert Fraser Wrote:Oskar Linde wrote:I think that you have the right suggestion here: what's wrong about the complex is that it is a too specific mechanism, having a generic built-in postfix unit mechanism would allow complex, quaternion, unit libraries.. which is very nice. In theory there is no difference between "cast(km)10 + cast(ft)13" and "10km + 13ft" but in practice there is a big one: the second one is much more readable! Regards, renoXWalter Bright wrote:The identifier "i" is rather frequently used, so I don;t think that's a good idea. I'd prefer an opPostfix or something that allows literals with postfixes to be converted to different types. This would be especially nice for dealing with units, i.e.: writef("%s", toMiles(10km + 13ft));The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the types built in are rendered irrelevant I see no reason not to take this opportunity to simplify the language. Regarding literals, I'd say this is would be an adequate replacement for the above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be a good thing. :)
Jan 07 2008
On Mon, 07 Jan 2008 13:21:21 -0000, renoX <renosky free.fr> wrote:Robert Fraser Wrote:Ignoring my previous post this rings a bell. I'm sure I've seen it in another language somewhere, probably a dynamic one.Oskar Linde wrote:I think that you have the right suggestion here: what's wrong about the complex is that it is a too specific mechanism, having a generic built-in postfix unit mechanism would allow complex, quaternion, unit libraries.. which is very nice. In theory there is no difference between "cast(km)10 + cast(ft)13" and "10km + 13ft" but in practice there is a big one: the second one is much more readable! Regards, renoXWalter Bright wrote:willThe issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, thisbuilthelp. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the typesin are rendered irrelevant I see no reason not to take thisopportunityto simplify the language. Regarding literals, I'd say this is would be an adequate replacementforthe above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be agoodthing. :)The identifier "i" is rather frequently used, so I don;t think that's a good idea. I'd prefer an opPostfix or something that allows literals with postfixes to be converted to different types. This would be especially nice for dealing with units, i.e.: writef("%s", toMiles(10km + 13ft));
Jan 07 2008
Bruce Adams a crit :On Mon, 07 Jan 2008 13:21:21 -0000, renoX <renosky free.fr> wrote:Fortress has this: http://en.wikipedia.org/wiki/Fortress_%28programming_language%29 It's a language made by Sun for HPC. Regards, renoXRobert Fraser Wrote:Ignoring my previous post this rings a bell. I'm sure I've seen it in another language somewhere, probably a dynamic one.Oskar Linde wrote:I think that you have the right suggestion here: what's wrong about the complex is that it is a too specific mechanism, having a generic built-in postfix unit mechanism would allow complex, quaternion, unit libraries.. which is very nice. In theory there is no difference between "cast(km)10 + cast(ft)13" and "10km + 13ft" but in practice there is a big one: the second one is much more readable! Regards, renoXWalter Bright wrote:willThe issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, thisbuilthelp. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Sounds like a good idea. Complex math is probably only used in a very small subset of D code, and if most advantages of having the typesin are rendered irrelevant I see no reason not to take thisopportunityto simplify the language. Regarding literals, I'd say this is would be an adequatereplacement forthe above expression: 3 + 5*i And last, getting rid of the creal and ireal keywords can only be agoodthing. :)The identifier "i" is rather frequently used, so I don;t think that's a good idea. I'd prefer an opPostfix or something that allows literals with postfixes to be converted to different types. This would be especially nice for dealing with units, i.e.: writef("%s", toMiles(10km + 13ft));
Jan 08 2008
在 Mon, 07 Jan 2008 14:00:38 +0800,Walter Bright <newshound1 digitalmars.com> 写道:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.So it's time for implicitCastFrom? Use of imaginary literals would be limited, I can't think of a possible solution to (1+2i)*(3+5i) without support from current mechanism. Yet, I don't think that's a big deal. I don't see any possible compiler magic can deduce 1+2i firstly implicitly cast to a struct. What about the struct not getting any opMul? How well would the error be diagnosed? And even if the compiler is able to fulfill this, that means we prevent another struct/class to have implicitCastFrom(creal a) and one of opMul/opAdd/opSub/opDiv at the same time. ireal_struct myirealnumber = 2i; would work as expected by the implicitCastFrom magic. struct ireal_struct { implicitCastFrom(creal a) // and implement cfloat?, cdouble?, for different case we get different data size. use a enum to store the number? { static if( compile_time_get_real_part_func(a) != 0 ) pragma(msg,"You can't cast a non pure imaginary number to pure imaginary number."); ... } ... } The problem is that the compiler won't be able to accurately report the line of code, and not to say which column. static assert won't give you a back trace. Also I don't know the compile_time_get_real_part_func? How to get the real part or the imaginary part of a number at compile time? seems it's not yet possible. And hopefully, DMD would get the column info in the future as DMC. How to get that column info at compile time? This would make the diagnostic system becoming complexier. But if we don't implement this in the future, we get the diagnostic system inconsistency. Just like at the moment, we get some error with line numbers, while some are not. Currently I can only see three keywords which can be eliminated (ireal,ifloat,idouble). But if we want to eliminate cfloat,cdouble,creal, we come to a problem : what's typeof(3+5i)? Regards, David -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Jan 06 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.There is also the advantage of standardisation, although I don't think it's a strong argument -- AFAIK, C++ hasn't had a problem with multiple incompatible definitions of Complex. I imagine that game programmers ask, if complex numbers are built-in, why not quaternions too? I think the argument for pure imaginary types is extremely weak. They are very annoying to work with, because they aren't closed under multiplication. This is a nasty property to have in a built-in type. Suppose you're writing a generic function product(T)(T[]) which returns T[0]*T[1]*T[2]*... What's the return type? Suppose T is idouble. Then if the number of elements in T is odd, the return type should be idouble, but if it's even, the return type should be double! You could promote it to complex with a construction like typeof(1?T*T:T), but that's inefficient, and negates most of the benefits of having a imaginary type. As far as I can tell, the imaginary types could be removed even if the literal problem was not solved (the compiler could continue to keep track of imaginary literals internally, but promote them to complex whenever a type is required). But a solution to the literal problem would be impressive.
Jan 07 2008
On Mon, 07 Jan 2008 09:05:45 +0100, Don Clugston wrote:There is also the advantage of standardisation, although I don't think it's a strong argument -- AFAIK, C++ hasn't had a problem with multiple incompatible definitions of Complex. I imagine that game programmers ask, if complex numbers are built-in, why not quaternions too? I think the argument for pure imaginary types is extremely weak. They are very annoying to work with, because they aren't closed under multiplication. This is a nasty property to have in a built-in type. Suppose you're writing a generic function product(T)(T[]) which returns T[0]*T[1]*T[2]*... What's the return type? Suppose T is idouble. Then if the number of elements in T is odd, the return type should be idouble, but if it's even, the return type should be double! You could promote it to complex with a construction like typeof(1?T*T:T), but that's inefficient, and negates most of the benefits of having a imaginary type. As far as I can tell, the imaginary types could be removed even if the literal problem was not solved (the compiler could continue to keep track of imaginary literals internally, but promote them to complex whenever a type is required). But a solution to the literal problem would be impressive.I agree with Don (how could I not? :D), although I really have little understanding of the technical internals. Several years ago, when I first started using D, I was working on an electronics engineering course. One of my first bug reports was on D complex arithmetic. So it may be useful in some special fields, but I really don't see how it is a critical special case in D; a suitable replacement using structs would probably be more than sufficient. Furthermore, creal and ireal came across as an oxymoron. -JJR
Jan 07 2008
Don Clugston wrote:Suppose you're writing a generic function product(T)(T[]) which returns T[0]*T[1]*T[2]*... What's the return type? Suppose T is idouble. Then if the number of elements in T is odd, the return type should be idouble, but if it's even, the return type should be double!I definitely don't pretend to understand any of that, but shouldn't it all follow the pertinent trails of mathematics? As in, case one, idouble; case two, double -- and the latter should probably be an idouble where one of the parts of the result De Facto makes it double, while still technically being an idouble. Any further calculation that wants to perceive a difference, might then start with checking whether the argument is "in practice a double, or really idouble".
Jan 07 2008
Georg Wrede wrote:Don Clugston wrote:The bottom line is that there really is no useful mathematics that can be performed using only imaginary numbers. If to do anything more than add, subtract, or multiply by a (real!) scalar they become complex. If you have any imaginary numbers in a numerical code it means you're working in the complex plane. I don't think there is even a mathematical symbol reserved for the set of pure imaginary numbers. For reals there's the double-barred R, for complex numbers there's double-barred C, but there's no double barred "I" as far as I know. It just isn't useful, because, as Don says, its not closed under the common mathematical operations. --bbSuppose you're writing a generic function product(T)(T[]) which returns T[0]*T[1]*T[2]*... What's the return type? Suppose T is idouble. Then if the number of elements in T is odd, the return type should be idouble, but if it's even, the return type should be double!I definitely don't pretend to understand any of that, but shouldn't it all follow the pertinent trails of mathematics? As in, case one, idouble; case two, double -- and the latter should probably be an idouble where one of the parts of the result De Facto makes it double, while still technically being an idouble. Any further calculation that wants to perceive a difference, might then start with checking whether the argument is "in practice a double, or really idouble".
Jan 07 2008
Bill Baxter wrote:Georg Wrede wrote:Right. In practice, I've found that you always convert ireal to real whenever you want to do anything interesting. 100% of the benefits of ireal could be obtained by including a guaranteed optimisation that complexA * realR * complex_literalB becomes simply complex(-A.im*R*B.im, A.re*R*B.im) when the literal B has a real part of zero. (and similarly for division). Note that if the literal is 1i, then R behaves exactly as an ireal. The *only* difference is that the programmer has to remember that it's imaginary (by multiplying by 1i) instead of the compiler remembering it in the type.Don Clugston wrote:The bottom line is that there really is no useful mathematics that can be performed using only imaginary numbers. If to do anything more than add, subtract, or multiply by a (real!) scalar they become complex. If you have any imaginary numbers in a numerical code it means you're working in the complex plane. I don't think there is even a mathematical symbol reserved for the set of pure imaginary numbers. For reals there's the double-barred R, for complex numbers there's double-barred C, but there's no double barred "I" as far as I know. It just isn't useful, because, as Don says, its not closed under the common mathematical operations.Suppose you're writing a generic function product(T)(T[]) which returns T[0]*T[1]*T[2]*... What's the return type? Suppose T is idouble. Then if the number of elements in T is odd, the return type should be idouble, but if it's even, the return type should be double!I definitely don't pretend to understand any of that, but shouldn't it all follow the pertinent trails of mathematics? As in, case one, idouble; case two, double -- and the latter should probably be an idouble where one of the parts of the result De Facto makes it double, while still technically being an idouble. Any further calculation that wants to perceive a difference, might then start with checking whether the argument is "in practice a double, or really idouble".
Jan 08 2008
Reply to Don,100% of the benefits of ireal could be obtained by including a guaranteed optimisation that complexA * realR * complex_literalB becomes simply complex(-A.im*R*B.im, A.re*R*B.im) when the literal B has a real part of zero. (and similarly for division).This is starting to touch on something I have been wanting: compile time access to literals. In my backmath lib you can't use literal values: A + B = C * 3; // fails 3 is of wrong type One thing that would fix this quite well would be to allow a "constant cast" where constant is really constant. with this: Value!(v) implicitCast(real v)(){return Value!(v).init} the above processes as: A + B = C * implicitCast!(3)(); Having access to literal values at the typing stage would allow all kinds of cool stuff at compile time.
Jan 08 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.I never use them in the style of code I write, so I personally wouldn't miss them. I think for code that does need it, if (and only if) the same performance benefits can be seen in a struct, it will simplify the language enough to justify their removal.
Jan 07 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.I defer to Don on this one :-) But I will say I seem to have heard arguments like this pretty often: "Well complex numbers are built-in, and my <new confoobulator> will be used at least as much as complex numbers." So that seems a little telling to me. I personally haven't had much need for complex numbers, but I maintain wrappers for a number of Fortran math libraries which have APIs for cfloat and cdouble. My main fear is just that going from built-in to not means I'll need to maintain different versions of these for D1.0, D2.0, and maybe D2.0/Tango when that comes out. Right now I think they're pretty much version independent. --bb
Jan 07 2008
On Mon, 07 Jan 2008 08:35:20 -0000, Bill Baxter <dnewsgroup billbaxter.com> wrote:Walter Bright wrote:You must surely have noticed people using all kinds of weird and wonderful excuses as justifications for their pet new syntax feature proposal. I think complex numbers like any other feature have to stand or not on their own.The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.I defer to Don on this one :-) But I will say I seem to have heard arguments like this pretty often: "Well complex numbers are built-in, and my <new confoobulator> will be used at least as much as complex numbers." So that seems a little telling to me.I personally haven't had much need for complex numbers, but I maintain wrappers for a number of Fortran math libraries which have APIs for cfloat and cdouble. My main fear is just that going from built-in to not means I'll need to maintain different versions of these for D1.0, D2.0, and maybe D2.0/Tango when that comes out. Right now I think they're pretty much version independent. --bbMy own feeling is if it ain't broke don't fix it. Walter must have something up his sleeve if he's thinking of changing it. It could just be cosmetic. Its common in a new language for features to be hard coded and gradually replaced with libraries as the language becomes strong enough to support better modularity. I can't think of any other language where complex numbers are built in rather than a library (only because I've never looked mind). However, I can't think of any language that has a rich enough syntax to let you write 3+5i like that. Though I can see it happening in a duck typed language. Bruce.
Jan 07 2008
Bruce Adams wrote:On Mon, 07 Jan 2008 08:35:20 -0000, Bill Baxter <dnewsgroup billbaxter.com> wrote:I think he's sensitive about the number-of-keywords argument people sometimes bring up against D. The count for D could drop by 6 by making complex numbers a library. Anyway, as Don so eloquently pointed out, pure imaginary types of any form don't make much sense in a programming language.Walter Bright wrote:You must surely have noticed people using all kinds of weird and wonderful excuses as justifications for their pet new syntax feature proposal. I think complex numbers like any other feature have to stand or not on their own.The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.I defer to Don on this one :-) But I will say I seem to have heard arguments like this pretty often: "Well complex numbers are built-in, and my <new confoobulator> will be used at least as much as complex numbers." So that seems a little telling to me.I personally haven't had much need for complex numbers, but I maintain wrappers for a number of Fortran math libraries which have APIs for cfloat and cdouble. My main fear is just that going from built-in to not means I'll need to maintain different versions of these for D1.0, D2.0, and maybe D2.0/Tango when that comes out. Right now I think they're pretty much version independent. --bbMy own feeling is if it ain't broke don't fix it. Walter must have something up his sleeve if he's thinking of changing it. It could just be cosmetic.Its common in a new language for features to be hard coded and gradually replaced with libraries as the language becomes strong enough to support better modularity. I can't think of any other language where complex numbers are built in rather than a library (only because I've never looked mind). However, I can't think of any language that has a rich enough syntax to let you write 3+5i like that. Though I can see it happening in a duck typed language.I know of two: Fortran and python both have complex numbers built in (but neither has a built-in pure imaginary type). Fortran has em because the language was designed mainly for engineering work, and engineers can't live without complex numbers. At least back in 1977 Fortran had no way to define user types, so built-in was the obvious choice. I'm not sure why Python has them built-in. It doesn't really seem necessary. Maybe Guido just wanted to draw in the engineers. It even uses the engineering convention of j for sqrt(-1). 1+1j rather than 1+1i. --bb
Jan 07 2008
Bruce Adams wrote:I can't think of any other language where complex numbers are built in rather than a library (only because I've never looked mind).Python, C and Fortran.
Jan 07 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.While some way to write complex literals would be neat (because presumably it would open the door to being able to make literal syntaxes for all user types) I don't think it's really a killer. It's not very common to use lots of literals. For a command-line tool not having a literal syntax can be a bummer, but for a programming language it's bad practice to have a lot of magic literals in your code anyway. I.e. creal rot45 = creal(.707, 707); creal xr = rot45 * x; is better than creal xr = (.707 + 0.707i) * x; in my opinion. As long as complex constants can still be put in static arrays, it should be ok. --bb
Jan 07 2008
Bill Baxter:but for a programming language it's bad practice to have a lot of magic literals in your code anyway. I.e. creal rot45 = creal(.707, 707); creal xr = rot45 * x; is better than creal xr = (.707 + 0.707i) * x; in my opinion. As long as complex constants can still be put in static arrays, it should be ok.Python has the literals too:(5+0j)complex(5)(1.6666666666666665-1.6666666666666665j)(6 + 2j - 1 + 3j) / 3j(-0.33333333333333331-1.6666666666666665j) But maybe imaginary literals aren't necessary: C++ complex<long double> a = 5; complex<long double> b(0,7); c = a + b + complex<long double>(0,7); Current D: creal a = 5; ireal b = 7i; c = a + b + 7i; Alternative: auto a = creal(5); // == creal(5,0) auto b = ireal(7); c = a + b + ireal(7); C++: c = (complex<double>(6,2) + complex<double>(-1,3)) / complex<double>(0,3); Current D: c = (6 + 2i - 1 + 3i) / 3i; Alternative: c = (creal(6,2) + cdouble(-1,3)) / idouble(3); Bye, bearophile(complex(6, 2) - complex(1, 3)) / complex(0,3)
Jan 07 2008
Walter Bright wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs?Assuming the opponents of the D programming language are not reading this, I'd like to remind you of the upsides. A language that is C(++) like, and that endorses Complex and Imaginary types right in the language itself, gains a few points in any "cross-the-tees" language comparison. Additionally, while any "self-respecting professional" doesn't let his reputation degrade into falling for such "mundaneties", some of the critics (especially those who actually are capable of creating their own opinion based on their experience and intellect, as opposed to the average opinion at the golf club), surely would welcome the notion of having these data types chiseled right into the language -- irrespectively of whether there is a Canonical library implementation or not.All but one of the advantages of having them be core types can be addressed with advancing compiler technology.No argument there. But then, what is the whole point of the issue? IMHO, the notion of having them as Fundamental, or Canonical Types in the language, is totally decoupled from the fact that they are or not are handled in some "bundled library". The fact that they are recognised in the language itself, is far more valuable than whether they are at all (or Perfectly) addressed in some library (included or not, or even that you have to buy at (possibly outrageous) cost).Getting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue. I've studied languages, I've taught Computer Programming for years at University Level, and, to this day, I haven't got a compelling answer to "why less keywords is Better, "Even at the cost of confusing any or all of the students of a particular language"". I've also studied Natural Languages (as in Finnish, Swedish, English, German, Spanish, Russian, French), and during those years, I've gotten a fair idea of the relation of the number of words versus the number of concepts, and how these relate to the understandability and learning speed of them. As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison". (Do I have to say "const", anybody???")The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Yes, of course. If the standard library doesn't implement imaginary, then the most rational thing to do would be to write "import whatever.complex". In any case, the notation "3 + 5i" should be reserved for imaginary numbers, period. Whether the original compiler writer bothers to deliver the relevant library implementation or not, is besides the issue. A Serious Language ought to have this notation chiseled down. ========================================= Now, having said all that, if it turns out that Walter's ONLY suggestion here was that instead of simply using "3 + 5i" instead of preceding it with "import std.complex" -- please, then, disreagard this entire post. Still, some of my points may be valid even so. :-)
Jan 07 2008
Georg Wrede wrote:Walter Bright wrote:There is one thing we'd lose that hasn't been mentioned. We'd lose the ability to have complex template parameters. But maybe it's time to extend that capability to all value types, anyway.The issue comes up now and then about why have complex and imaginary types, rather than using structs?No argument there. But then, what is the whole point of the issue? IMHO, the notion of having them as Fundamental, or Canonical Types in the language, is totally decoupled from the fact that they are or not are handled in some "bundled library". The fact that they are recognised in the language itself, is far more valuable than whether they are at all (or Perfectly) addressed in some library (included or not, or even that you have to buy at (possibly outrageous) cost).You seem to be mixing up imaginary and complex. But anyway, as per Don's comment, regardless of what else happens it's probably a good idea to make 5i be a complex number with zero real part, rather than a pure imaginary number. And do away with the pure-imaginary types.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number.If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.I don't think it could really work that way. Upon encountering the text 3+5i the compiler has to know what sort of value to create. If it has to import a module to know what type that is then that module is going to have to be somehow hard-coded. The result is basically that it has to be a built-in type. Unless of course Walter invents a general way to associate literal suffixes with user types. --bbAssuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Yes, of course. If the standard library doesn't implement imaginary, then the most rational thing to do would be to write "import whatever.complex". In any case, the notation "3 + 5i" should be reserved for imaginary numbers, period.
Jan 07 2008
On Tue, 08 Jan 2008 04:38:44 +0200, Georg Wrede wrote:Wow... I've had the same feelings (without the experiences, however), but you elucidated a thought I've had in my mind for awhile about the "too many keywords" problem. I wasn't sure how to express it, nor do I really have the language background to make the argument stronger. It seems to me that the languages (computer or natural) with more vocabulary are more expressive in describing an exact thought. Whereas simpler languages seem prone to use many context sensitive words that could only express complete thoughts with laborious diatribe (such is the result of limited vocabulary, I suppose, in any language). The advantage of reduced vocabulary is lost when simplicity of vocabulary causes a complexity of volume (and possibly ambiguity). There is a risk, therefore, of communication being lost. Whereas, increased vocabulary seems to simplify the sentence at the expense of comprehension (the issuer and receiver must memorize more words and understand more meanings). Once again, there's a another risk of the communication being lost. So, which is the worse evil? When it comes to natural languages, there are thousands of words to memorize, and developing a vocabulary is a constant challenge for language learners. In the case of computer languages, the keyword vocabulary is a minuscule fraction of the natural language, so it would seem unreasonable for us to worry about such additions, especially if they improve the languages ability to express exact meaning. But this is hardly original thought when it comes to language design, I'm sure. For those that have studied language design, I imagine this is probably one of the first things discussed. I'm not sure if I'm babbling on with this, but I just wanted to voice some sort of agreement with Georg's take on this. -JJRGetting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue. I've studied languages, I've taught Computer Programming for years at University Level, and, to this day, I haven't got a compelling answer to "why less keywords is Better, "Even at the cost of confusing any or all of the students of a particular language"". I've also studied Natural Languages (as in Finnish, Swedish, English, German, Spanish, Russian, French), and during those years, I've gotten a fair idea of the relation of the number of words versus the number of concepts, and how these relate to the understandability and learning speed of them. As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison". (Do I have to say "const", anybody???")
Jan 07 2008
John Reimer wrote:I'm not sure if I'm babbling on with this, but I just wanted to voice some sort of agreement with Georg's take on this.Yes, it was well expressed and I feel much the same. Sean
Jan 08 2008
Georg Wrede wrote:Assuming the opponents of the D programming language are not reading this, I'd like to remind you of the upsides.Sure. Hearing both sides is why I posted the query.A language that is C(++) like, and that endorses Complex and Imaginary types right in the language itself, gains a few points in any "cross-the-tees" language comparison. Additionally, while any "self-respecting professional" doesn't let his reputation degrade into falling for such "mundaneties", some of the critics (especially those who actually are capable of creating their own opinion based on their experience and intellect, as opposed to the average opinion at the golf club), surely would welcome the notion of having these data types chiseled right into the language -- irrespectively of whether there is a Canonical library implementation or not.I wouldn't remove it from the core language without having a complete standard library implementation ready to go.IMHO, the notion of having them as Fundamental, or Canonical Types in the language, is totally decoupled from the fact that they are or not are handled in some "bundled library".I don't agree. Things that should go into the core language are things that don't work very well as libraries. If they do work well as libraries, then it's hard to see the value of putting them in the core.The fact that they are recognised in the language itself, is far more valuable than whether they are at all (or Perfectly) addressed in some library (included or not, or even that you have to buy at (possibly outrageous) cost).They'd be standardized and included with any standard conforming D implementation.While I agree that lots-o-keywords is not necessarily a bad thing, it is an indication that all might not be well with the language design. A perfect language would have a very small number of orthogonal concepts, from which elegant constructs can be built. For example, closures are a simple concept, which obsoletes the more complex feature functors.Getting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue. I've studied languages, I've taught Computer Programming for years at University Level, and, to this day, I haven't got a compelling answer to "why less keywords is Better, "Even at the cost of confusing any or all of the students of a particular language"". I've also studied Natural Languages (as in Finnish, Swedish, English, German, Spanish, Russian, French), and during those years, I've gotten a fair idea of the relation of the number of words versus the number of concepts, and how these relate to the understandability and learning speed of them. As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison".(Do I have to say "const", anybody???")Oddly enough, the current const regime is the simplest of all the proposals.I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 07 2008
What about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c = 1+5i + 2+3i + 6i; complex c = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 08 2008
Daniel919, el 8 de enero a las 12:22 me escribiste:What about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c = 1+5i + 2+3i + 6i; complex c = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }+1 -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Sus discipulos se miraron sin entended hasta que uno preguntose: Peperino, soy Daniel Q. de Olivos tengo 54 años y aún soy virgen. A lo que Peperino respondiole: Si sos ganso, ganso ser. Y lo frotó, y lo curó y lo sanó. A lo que todos dijeron: ¡¡¡Peperino se la come, Peperino se la come!!! -- Peperino Pómoro
Jan 08 2008
Walter Bright Wrote:I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.Any time a hack is needed, it's probably not the best solution. Somewhere in this thread, people talked about a generic interface for postfix labels. Examples given were i, ft, km. I'd be really cool to see something like that make its way into the language instead of a hack.
Jan 08 2008
Jason House wrote:Walter Bright Wrote:I'd rather it were not. It reduces clarity, since the postfixes will be short and there will be a lot of collisions and it won't be clear where they are defined.I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.Any time a hack is needed, it's probably not the best solution. Somewhere in this thread, people talked about a generic interface for postfix labels. Examples given were i, ft, km. I'd be really cool to see something like that make its way into the language instead of a hack.
Jan 08 2008
Walter Bright wrote:Georg Wrede wrote:I thought the standard library's inclusion in the language spec was one of the things you disliked about C++. Though you're right there is effective precedent for it, with the compiler recognizing std.intrinsic and various parts of std.math as a QOI feature. However, this has proven to be quite a headache for libraries with alternate path schemes, like Tango. I'll admit to also being a bit concerned that this may produce another binding between the runtime and standard library, much like the regex features did. I'm all for retaining imaginary literals, but I hope the solution is carefully considered. SeanI do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 08 2008
Walter Bright wrote:Georg Wrede wrote: While I agree that lots-o-keywords is not necessarily a bad thing, it is an indication that all might not be well with the language design. A perfect language would have a very small number of orthogonal concepts, from which elegant constructs can be built.Lisp? :-) But seriously, I'd say that once you have a well designed language, the number of keywords automagically stays low. But any cheating (as in overloading words, for example) makes the language harder to use and/or harder to learn. Almost as bad is when one contemplates the inclusion of a new concept into the language, and in hindsight finds himself having decided according to whether the concept needs a new keyword. (Hell, I'd almost swear I've seen that happen sometime. :-) )(Sloppily referred to the old const...)(Do I have to say "const", anybody???")Oddly enough, the current const regime is the simplest of all the proposals.No argument there!
Jan 08 2008
Georg Wrede wrote:Getting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue.As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison". (Do I have to say "const", anybody???")There's a funny thing about this situation. Here's the background: * I argued (on the ng) against overloading the 'enum' keyword to mean manifest constants. * Andrei emailed me, basically saying that we need to keep the keyword count down. * I responded that if we want to get the keyword count down, an obvious way to do it would be to remove the pure imaginary types. * Andrei discussed this with Walter. Essentially, I don't think that pure imaginary types belong in the language (not even in a standard library). And getting rid of them would be great news for those who care about keyword count. The complex types are different; the _only_ reason you'd remove them is to reduce the keyword count. That's a completely different issue. -Don.
Jan 08 2008
Don Clugston wrote:Georg Wrede wrote:This should NEVER be an isolated goal. Rather, it should just be the natural result of good language design. And only that. BASIC and Brainf**k have fewer keywords than D, but I wouldn't call them better than D.Getting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue.As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison". (Do I have to say "const", anybody???")There's a funny thing about this situation. Here's the background: * I argued (on the ng) against overloading the 'enum' keyword to mean manifest constants. * Andrei emailed me, basically saying that we need to keep the keyword count down.* I responded that if we want to get the keyword count down, an obvious way to do it would be to remove the pure imaginary types. * Andrei discussed this with Walter. Essentially, I don't think that pure imaginary types belong in the language (not even in a standard library). And getting rid of them would be great news for those who care about keyword count. The complex types are different; the _only_ reason you'd remove them is to reduce the keyword count. That's a completely different issue.Of course, the fewness of keywords can be perceived as a measure of good language design. But decreasing the number of keywords artificially doesn't make any language better. "Have as few keywords as practical, but NO fewer than that!"
Jan 08 2008
Georg Wrede wrote:Don Clugston wrote:I agree completely. It's the typical problem you get with any indirect metric. Keyword count can be a measure of language complexity, but you can fall into the horrible trap of making the language more complicated in order to reduce the number of keywords. It becomes a useless metric if you start to optimise for it.Georg Wrede wrote:This should NEVER be an isolated goal. Rather, it should just be the natural result of good language design. And only that. BASIC and Brainf**k have fewer keywords than D, but I wouldn't call them better than D.Getting rid of them will release 6 keywords, and make the core language simpler.Now, this is the one subject that gets me downright ballistic. During the (some six) years I've been a part of D, I have constantly had a problem with this keyword number issue.As a result of this all, I'm definitely of the opinion that "one concept warrants one word", and that "the same word for different purposes is poison", and that "the same concept with different words is poison". (Do I have to say "const", anybody???")There's a funny thing about this situation. Here's the background: * I argued (on the ng) against overloading the 'enum' keyword to mean manifest constants. * Andrei emailed me, basically saying that we need to keep the keyword count down.* I responded that if we want to get the keyword count down, an obvious way to do it would be to remove the pure imaginary types. * Andrei discussed this with Walter. Essentially, I don't think that pure imaginary types belong in the language (not even in a standard library). And getting rid of them would be great news for those who care about keyword count. The complex types are different; the _only_ reason you'd remove them is to reduce the keyword count. That's a completely different issue.Of course, the fewness of keywords can be perceived as a measure of good language design. But decreasing the number of keywords artificially doesn't make any language better."Have as few keywords as practical, but NO fewer than that!"
Jan 08 2008
Georg Wrede wrote:Of course, the fewness of keywords can be perceived as a measure of good language design. But decreasing the number of keywords artificially doesn't make any language better. "Have as few keywords as practical, but NO fewer than that!"I wrote a programming language that used only 26 keywords: a,b,c,d... Of course, each keyword had a subtly different meaning depending on its context... ;)
Jan 09 2008
Walter Bright Wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.As a physicist who uses D for simulations, my answer is NO! Your original cited papers are good reasons NOT to do this. You should also go re-read what YOU wrote on the subject and the papers you cited. I don't think that releasing those keywords really makes the language much less "complex." Making the language "less" complex entitles making things intuitive, and things that are not intuitive clearly documented! -S.
Jan 08 2008
On Mon, 07 Jan 2008 09:00:38 +0300, Walter Bright <newshound1 digitalmars.com> wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types."No issue left behind" Why don't we remove or at least shorten foreach_reverse too?
Jan 10 2008
naryl:Why don't we remove or at least shorten foreach_reverse too?Removing: -1. It's actually useful (I'd like to see more iteration constructs, not less). Shortening: it's long, so maybe yes, if you/someons find(s) something better. Do you have some suggestions? Bye, bearophile
Jan 10 2008
On Fri, 11 Jan 2008 04:03:46 +0300, bearophile <bearophileHUGS lycos.com> wrote:naryl:Let me quote Regan Heath: In article <opsmol1osx23k2f5 ally>, Regan Heath says...Why don't we remove or at least shorten foreach_reverse too?Removing: -1. It's actually useful (I'd like to see more iteration constructs, not less). Shortening: it's long, so maybe yes, if you/someons find(s) something better. Do you have some suggestions? Bye, bearophileDoes the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with Regan. foreach don't need to imply any direction. Compiler must be able to parallelize it. For iteration constructs with implied direction my favourite is: foreach(forward) foreach(reverse) foreach(forward, firstEvenThenOdd) etc -- naryl
Jan 10 2008
naryl wrote:On Fri, 11 Jan 2008 04:03:46 +0300, bearophile <bearophileHUGS lycos.com> wrote:IMHO both foreach_reverse *and* foreach are ugly hacks and should be removed in D2. let me quote a related post:naryl:Let me quote Regan Heath: In article <opsmol1osx23k2f5 ally>, Regan Heath says...Why don't we remove or at least shorten foreach_reverse too?Removing: -1. It's actually useful (I'd like to see more iteration constructs, not less). Shortening: it's long, so maybe yes, if you/someons find(s) something better. Do you have some suggestions? Bye, bearophileDoes the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with Regan. foreach don't need to imply any direction. Compiler must be able to parallelize it. For iteration constructs with implied direction my favourite is: foreach(forward) foreach(reverse) foreach(forward, firstEvenThenOdd) etc -- narylSorry, to use the web interface to the newsgroup.. This is an old (1993), but I hope related, discussion: Iterators: Signs of Weakness in Object-Oriented Languages http://home.pipeline.com/~hbaker1/Iterator.html - PaulI think the solution should be a more general approach: a) use the functional approach with mapping and filter functions. According to the article in the quote such an implementation requires full closures which D 2.x has. this could be implemented in a library. so with that approach I could use the ruby way of: --- collection.each BlockOfCode or in D: collection.each ((item a) {...code...}); or with free functions: map(item[], (item a) {...code...}); --- b) for iterations where order is important, maybe implement generators (also mentioned in the above article). just my 2 cents. --Yigal
Jan 11 2008
Yigal Chripun wrote:IMHO both foreach_reverse *and* foreach are ugly hacks and should be removed in D2.I can see how we might choose to remove foreach_reverse (assuming that DMD can properly inline loops...another post suggested that it currently could not). However, I wanted to speak up in favor of foreach(): IMHO, it is an exceptionally useful tool because it provides auto-translation of the "continue", "break", and "return" semantics. Can you imagine the syntax required to emulate a return out of a loop body if foreach didn't do it for you? Sure, you could do it by hand, but it'd be very ugly. foreach() is such a common paradigm that I think that the syntax sugar is worth it. MHO.
Jan 11 2008
Yigal Chripun Wrote:I think the solution should be a more general approach: a) use the functional approach with mapping and filter functions. According to the article in the quote such an implementation requires full closures which D 2.x has. this could be implemented in a library. so with that approach I could use the ruby way of: --- collection.each BlockOfCode or in D: collection.each ((item a) {...code...}); or with free functions: map(item[], (item a) {...code...}); --- b) for iterations where order is important, maybe implement generators (also mentioned in the above article). just my 2 cents. --YigalMy $0.02: IMO, were D conceived as a functional language, or one that was far more FP oriented, this probably would have been included early on. True closures are going to open up a *lot* of possibilities. However, D is much more procedural in it's grammar to make the outright removal of foreach() a good idea; I think it's kind of part of D's heritage and DNA to an extent. Comfort, familiarity and ease-of-use with foreach() trumps normalizing the language in favor of a more general construct. Also D has a foreach() construct that is hands-down better than what Java has, so why throw it away? That said, you're right about the library approach. I'd love to use that in my code when/if the opportunity presents itself. Python's map() has spoiled me so.
Jan 11 2008
Pragma:True closures are going to open up a *lot* of possibilities.I'm waiting to see the first one bold enough to define and use monads with the new closures of D ;-) (While I am not waiting to see the first Y). Bye, bearophile
Jan 11 2008
bearophile wrote:naryl:Ever since the language got the ability to use delegates as the foreach aggregate, there has been no need for foreach_reverse. Ironically enough, that's the same release foreach_reverse was added (0.170). Arrays should just have a built-in .reverseview (or whatever) property which returns a delegate for iterating over the array in reverse order. And add .sortedview while you're at it. -- E-mail address: matti.niemenmaa+news, domain is iki (DOT) fiWhy don't we remove or at least shorten foreach_reverse too?Removing: -1. It's actually useful (I'd like to see more iteration constructs, not less). Shortening: it's long, so maybe yes, if you/someons find(s) something better. Do you have some suggestions?
Jan 11 2008
Matti Niemenmaa wrote:bearophile wrote:And the only reason this isn't how its done is because dmd is unable to inline functions containing loops, thus foreach_reverse is the faster solution for built in arrays. -- Oskarnaryl:Ever since the language got the ability to use delegates as the foreach aggregate, there has been no need for foreach_reverse. Ironically enough, that's the same release foreach_reverse was added (0.170). Arrays should just have a built-in .reverseview (or whatever) property which returns a delegate for iterating over the array in reverse order. And add .sortedview while you're at it.Why don't we remove or at least shorten foreach_reverse too?Removing: -1. It's actually useful (I'd like to see more iteration constructs, not less). Shortening: it's long, so maybe yes, if you/someons find(s) something better. Do you have some suggestions?
Jan 11 2008
Matti Niemenmaa wrote:Arrays should just have a built-in .reverseview (or whatever) property which returns a delegate for iterating over the array in reverse order. And add .sortedview while you're at it.+1. I really like this idea (if the inlining thing could be worked out).
Jan 11 2008
Daniel919 Wrote:Here's my version from a while back: http://www.digitalmars.com/d/archives/digitalmars/D/Suffix-based_literal_syntax_53992.html -- ReinerWhat about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c = 1+5i + 2+3i + 6i; complex c = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 11 2008
"Reiner Pope" <none here.com> kirjoitti viestiss news:fm9kta$2f2e$1 digitalmars.com...Daniel919 Wrote:I agree - this suffix support should make it into the language. It would be a generic way of handling imaginary values, SI-units, etc. However, in your post from May, you say alphabetic. I'd rather have the suffix alphanumeric, with the first character locket to alphabetic - as we may need to express square meters, cubic feet etc., eg. in a general-purpose unit library.Here's my version from a while back: http://www.digitalmars.com/d/archives/digitalmars/D/Suffix-based_literal_syntax_53992.htmlWhat about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c = 1+5i + 2+3i + 6i; complex c = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 12 2008
Reiner Pope a crit :Daniel919 Wrote:I like a lot all those proposal for adding suffix based literal, but I'm afraid that these could interfere(sp?) with the ones already existing in the language, so I wonder if 'library added' suffix shouldn't have an operator to distinguish them for the language one. I'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f), if there is no operator, there are some risk of ambiguity: "5.8fm" is-it 5.8f meters or 5.8 femtometers? With 5.8f_m and 5.8_fm you remove the ambiguity and the _ is visually 'pleasing' so this syntax would still be used. Regards, renoXHere's my version from a while back: http://www.digitalmars.com/d/archives/digitalmars/D/Suffix-based_literal_syntax_53992.html -- ReinerWhat about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c = 1+5i + 2+3i + 6i; complex c = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }I do too. And been thinking along the lines of simply putting a hack in that the postfix 'i' means that it's a literal of type 'imaginary', and the compiler looks to see if "std.complex" was imported. This isn't as outlandish as it sounds, as there's precedent for it both in C++ <typeinfo> and java.lang.String, as well as D's Object.The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean an imaginary number. If one has the library delivered right with the standard compiler or if one has to walk around the Globe in search of the One library that actually implements it, I'd still want to have this particular notation reserved (in the Language Grammar itself) for this particular purpose.
Jan 12 2008
I agree, T opSuff_k(T)(T x) { return x * 1000; } is better to handle than T opPostfix("k")(T)(T x) { return x * 1000; } For example alias somefunc opSuff_k; would be too difficult with the other syntax.Here's my version from a while back: http://www.digitalmars.com/d/archives/digitalmars/D/Suffix-based_literal_syntax_53992.htmlI like a lot all those proposal for adding suffix based literal, but I'm afraid that these could interfere(sp?) with the ones already existing in the language, so I wonder if 'library added' suffix shouldn't have an operator to distinguish them for the language one. I'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f), if there is no operator, there are some risk of ambiguity: "5.8fm" is-it 5.8f meters or 5.8 femtometers? With 5.8f_m and 5.8_fm you remove the ambiguity and the _ is visually 'pleasing' so this syntax would still be used.What about: auto a = 5.8f m; auto b = 5fm; //<=> auto b = 5 fm; auto c = 5.8f fm; And the compiler always tries to find the longest match.
Jan 12 2008
You could just express "float km" like this: (5.8f)km. renoX Wrote:I like a lot all those proposal for adding suffix based literal, but I'm afraid that these could interfere(sp?) with the ones already existing in the language, so I wonder if 'library added' suffix shouldn't have an operator to distinguish them for the language one. I'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f), if there is no operator, there are some risk of ambiguity: "5.8fm" is-it 5.8f meters or 5.8 femtometers? With 5.8f_m and 5.8_fm you remove the ambiguity and the _ is visually 'pleasing' so this syntax would still be used. Regards, renoX
Jan 12 2008
On 1/12/08, renoX <renosky free.fr> wrote:I'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f),Why not the asterisk? Oh wait! - We already /have/ that functionality! 5.8f*km is replaced by km.opMul_r(5.8f); Seems to me that nothing new is needed.
Jan 12 2008
Janice Caron a crit :On 1/12/08, renoX <renosky free.fr> wrote:Because 1) when we write physic equation we don't write "5.0 x km" (x being the multiplication sign) but "5.0 km" so it would be nice if the language supported a way to make similar notations. 2) this could makes unneeded additional multiplication. 3) When you write "5km" you don't mean 5 * 1km but km(5), but sure most of the time it's the same.. Regards, renoXI'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f),Why not the asterisk? Oh wait! - We already /have/ that functionality! 5.8f*km is replaced by km.opMul_r(5.8f); Seems to me that nothing new is needed.
Jan 12 2008
Why not the asterisk? Oh wait! - We already /have/ that functionality! 5.8f*km is replaced by km.opMul_r(5.8f); Seems to me that nothing new is needed.Here are some ideas how it would be even better than it could be with opSuff. (opSuff would not allow: "z=5i;" <=> "z=5*i;") ----------------------------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(complex z) { return complex(re+z.re, im+z.im); } complex opAdd(real r) { return opAdd( complex(r,0) ); } //alias opAdd(real r) opAdd_r(real r); complex opAdd_r(real r) { return opAdd( r ); } complex opMul(complex z) { return complex(re*z.re-im*z.im, re*z.im+im*z.re); } complex opMul(real r) { return opMul( complex(r,0) ); } //alias opMul(real r) opMul_r(real r); complex opMul_r(real r) { return opMul( r ); } string toString() { return std.conv.toString(re) ~ "+" ~ std.conv.toString(im) ~ "i"; } struct i { static complex opMul_r(real im) { return complex(0,im); } //z=5*i; // static opJux_r(real im) { return complex(0,im); } //z=5i; //z=5f i; //z=5fi; is tricky, especially if "fi" is a symbol //but if "with(complex)" is used, "i" dominates over "fi", so this becomes: z=complex.i.opJux_r(5f); // static opExpr() { return complex(0,1); } //z=i; //is considered if none of the functions above matches //it would even be possible to make opExpr() the only function of i } } void main() { complex z; with(complex) z = 1+5*i + 2+3*i + 6*i; //maybe "with(complex)" can be inferred, when creating a complex? // complex z = 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( z ); } -----------------------------------------------
Jan 12 2008
Janice Caron escribi:On 1/12/08, renoX <renosky free.fr> wrote:But km, i, or whatever, must be at global scope, and then you couldn't have local variables named that way.I'm thinking about the underscore '_': 5.8f_km would be replaced by km(5.8f),Why not the asterisk? Oh wait! - We already /have/ that functionality! 5.8f*km is replaced by km.opMul_r(5.8f); Seems to me that nothing new is needed.
Jan 12 2008
renoX <renosky free.fr> wrote:Reiner Pope a =E9crit :=Daniel919 Wrote:The remaining advantage is that of imaginary literals, i.e. the i==postfix: 3 + 5iI'd really like to reserve the above phrase to be reserved to mean=he =an imaginary number. If one has the library delivered right with t==standard compiler or if one has to walk around the Globe in search==of the One library that actually implements it, I'd still want to =have this particular notation reserved (in the Language Grammar =k =itself) for this particular purpose.I do too. And been thinking along the lines of simply putting a hac=in that the postfix 'i' means that it's a literal of type ='imaginary', and the compiler looks to see if "std.complex" was ==imported. This isn't as outlandish as it sounds, as there's precedent for it =both in C++ <typeinfo> and java.lang.String, as well as D's Object.=What about a more general solution like ----------------------------- import std.stdio, std.conv; struct complex { real re; real im; complex opAdd(real r) { return complex(re+r, im); } complex opAdd_r(real r) { return complex(re+r, im); } complex opAdd(complex c) { return complex(re+c.re, im+c.im); } string toString() { return std.conv.toString(re) ~ "+" ~ =std.conv.toString(im) ~ "i"; } } //complex opPostfix("i")(T)(T im) { return complex(0,im); } void main() { // complex c =3D 1+5i + 2+3i + 6i; complex c =3D 1+complex(0,5) + 2+complex(0,3) + complex(0,6); writefln( c ); } ----------------------------- This would also allow real opPostfix("L")(T)(T x) { return x; } T opPostfix("k")(T)(T x) { return x * 1000; } meter opPostfix("m")(T)(T x) { return meter(x); }Here's my version from a while back: =ral_syntax_53992.htmlhttp://www.digitalmars.com/d/archives/digitalmars/D/Suffix-based_lite='m =-- ReinerI like a lot all those proposal for adding suffix based literal, but I=afraid that these could interfere(sp?) with the ones already existing =in =the language, so I wonder if 'library added' suffix shouldn't have an ==operator to distinguish them for the language one. I'm thinking about the underscore '_': 5.8f_km would be replaced by =km(5.8f), if there is no operator, there are some risk of ambiguity: ="5.8fm" is-it 5.8f meters or 5.8 femtometers? With 5.8f_m and 5.8_fm you remove the ambiguity and the _ is visually =='pleasing' so this syntax would still be used. Regards, renoXVotes++ In addition to removing ambiguity, requiring an initial underscore would= = lower the chance of collisions with other symbols. --- Simen Kjaeraas
Jan 14 2008
Walter Bright Wrote:The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Hello all, although perhaps a bit late the following are my points of view. * Presumably D has a very interesting future in numerics. As you clearly state in the Foreword of the recently published 'Learn to Tango with D', there is a gaping hole. An moreover the need for performance and flexibility. Definitely, D is a much better way to tackle the increasing complexity of the next coming numerical projects. * There is no numerics in D without scientists and engineers programming it in D. In this numerical programming field, as in many other aspects of life, there is the classic approach and the more vanguardist one. In the classic and conservative branch people use the good old Fortran, perhaps recycled into Fortran95: "runs fast, it's easy to learn and we know it well". In the more vanguardist and progressive branch people use the hardcore C++: "here is where the real power is", perhaps a mixture of Python and Fortran. Probably formal education tends to be much less interdisciplinary than many of us wish it would be... The people from engineering dedicated to numerics know their fluid dynamics quite well, but in general the C++ not that well. The people from informatics dedicated to numerics know their C++ quite well, but in general the fluid dynamics not that well. All this is quite reasonable... both worlds are overly complex! fluid dynamics is the task, the programming language is the tool, whose complexity can we reduce? probably both... Among other things this invites us to design a better programming language. Fortran people that are doing mix programming such as Python-Fortran will migrate to D, however the rest of the Fortran programmers might have prejudices... simplistic judgements are not uncommon: "How come D is supposed to be the promised land without the complex intrinsic (core) type?", "That's a step backwards!", "What about standardization? " these have been classic arguments from Fortran programmers against C++ in numerics. The same goes for the intrinsic (core) array syntax introduced in Fortran90. So in this context, although standardization might be a weak argument it has been used strongly. * As Don said, game programmers might wonder why complex deserve to be in the core language and not quaternions. I agree, however that reasoning is due to the biased criterion of a game programmer. I would dare to say that the reasons why complex numbers are studied in any basic course of mathematics (along with integers and real numbers) and not the quaternions are the same as why they might be a better candidate to be in the core language. * Again as Don said, the set of imaginary numbers has no practical use in mathematics. As Bill mentioned there is no set of the imaginary numbers defined in mathematics. Why should it be in a programming language? This would definitely strike a numerical analyst very weird! I think that if the type of complex numbers is in the core language it should respect the mathematical foundations, so why do we need the set of imaginary numbers? that definitely needs a redesign! * Complex numbers are very useful in numerics. They may be used in many situations as if they were reals. They may reduce differential operations to algebraic ones: solving a linear set of differential equations in the real field reduces to solving a linear set of algebraic equations in the complex field. This is just to mention a few... I am not claiming this is an argument for complex numbers to be in the core language as long as performance holds the same. Well, i think that is about all i wanted to say... Cheers!
Jan 14 2008
Pablo Ripolles:Fortran people that are doing mix programming such as Python-Fortran will migrate to D,Predicting the future isn't easy. Maybe they will migrate to Python + Cython (derived from Pyrex), or to Fortress (a neat language from Sun that I think D may learn something from), etc. And existing Pyd, they may even migrate to Python + Pyd + D ;-) Bye, bearophile
Jan 14 2008
bearophile Wrote:Pablo Ripolles:Indeed, predicting the future was not my intention. Yeah! that was an oversimplification... perhaps I should have written "might" or "would" instead of "will". Thanks!Fortran people that are doing mix programming such as Python-Fortran will migrate to D,Predicting the future isn't easy. Maybe they will migrate to Python + Cython (derived from Pyrex), or to Fortress (a neat language from Sun that I think D may learn something from), etc. And existing Pyd, they may even migrate to Python + Pyd + D ;-) Bye, bearophile
Jan 14 2008
Pablo Ripolles wrote:Walter Bright Wrote:ing language is the tool, whose complexity can we reduce? probably both... Among other things this invites us to design a better programming language. Fortran people that are doing mix programming such as Python-Fortran will migrate to D, however the rest of the Fortran programmers might have prejudices... simplistic judgements are not uncommon: "How come D is supposed to be the promised land without the complex intrinsic (core) type?", "That's a step backwards!", "What about standardization? " these have been classic arguments from Fortran programmers against C++ in numerics. The same goes for the intrinsic (core) array syntax introduced in Fortran90. So in this context, although standardization might be a weak argument it has been used strongly.The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Hello all, although perhaps a bit late the following are my points of view. * Presumably D has a very interesting future in numerics. As you clearly state in the Foreword of the recently published 'Learn to Tango with D', there is a gaping hole. An moreover the need for performance and flexibility. Definitely, D is a much better way to tackle the increasing complexity of the next coming numerical projects. * There is no numerics in D without scientists and engineers programming it in D. In this numerical programming field, as in many other aspects of life, there is the classic approach and the more vanguardist one. In the classic and conservative branch people use the good old Fortran, perhaps recycled into Fortran95: "runs fast, it's easy to learn and we know it well". In the more vanguardist and progressive branch people use the hardcore C++: "here is where the real power is", perhaps a mixture of Python and Fortran. Probably formal education tends to be much less interdisciplinary than many of us wish it would be... The people from engineering dedicated to numerics know their fluid dynamics quite well, but in general the C++ not that well. The people from informatics dedicated to numerics know their C++ quite well, but in general the fluid dynamics not that well. All this is quite reasonable... both worlds are overly complex! fluid dynamics is the task, the programm* As Don said, game programmers might wonder why complex deserve to be in the core language and not quaternions. I agree, however that reasoning is due to the biased criterion of a game programmer. I would dare to say that the reasons why complex numbers are studied in any basic course of mathematics (along with integers and real numbers) and not the quaternions are the same as why they might be a better candidate to be in the core language.Yes, my comment wasn't really fair. Complex numbers are fundamental to mathematics in a way that quaternions are not. But, imagine if quaternions were included, and treated in the same way as cdouble/idouble. We'd need quaternions, imaginary, complex, real, root_i, i*root_i, (root_i+imaginary), (root_i+i*root_i), (imaginary+i*root_i), (root_i+imaginary+i*root_i). (real +root_i+imaginary), (real +root_i+i*root_i), (real + imaginary+i*root_i). That's 12 types * { float, double, real} = 36 types! It's just not a viable approach.* Again as Don said, the set of imaginary numbers has no practical use in mathematics. As Bill mentioned there is no set of the imaginary numbers defined in mathematics. Why should it be in a programming language? This would definitely strike a numerical analyst very weird! I think that if the type of complex numbers is in the core language it should respect the mathematical foundations, so why do we need the set of imaginary numbers? that definitely needs a redesign!Imaginary numbers were included in D because they are in C99. Why are they in C99? It's because of a really obscure situation. (a.re + a.im * 1i)*(0.0 + b.im * 1i) is not the same as (a.re + a.im * 1i)*(b.im * 1i) if a.im or a.re is infinity. In the version where b.re is 0.0, a NaN is created, instead of the correct answer of 0. Ultimately this happens because 0.0 can mean either exactly 0, or 'too small to represent' (an underflow). As far as I can tell, D can avoid the need for a pure imaginary type, because *D guarantees constant folding, whereas C does not*. If constant folding is guaranteed, then with any compile-time complex constant, you know if it is a zero, or just an underflow. The problematic multiply-by-approximately zero can be eliminated -- it is known that it is a multiply-by-exactly zero. So we don't need the C99 hack of creating an entirely different type.* Complex numbers are very useful in numerics. They may be used in many situations as if they were reals. They may reduce differential operations to algebraic ones: solving a linear set of differential equations in the real field reduces to solving a linear set of algebraic equations in the complex field. This is just to mention a few... I am not claiming this is an argument for complex numbers to be in the core language as long as performance holds the same. Well, i think that is about all i wanted to say... Cheers!
Jan 14 2008
Don Clugston Wrote:Pablo Ripolles wrote:Oh, I see, I didn't know that! Thanks! Great answer!Walter Bright Wrote:ing language is the tool, whose complexity can we reduce? probably both... Among other things this invites us to design a better programming language. Fortran people that are doing mix programming such as Python-Fortran will migrate to D, however the rest of the Fortran programmers might have prejudices... simplistic judgements are not uncommon: "How come D is supposed to be the promised land without the complex intrinsic (core) type?", "That's a step backwards!", "What about standardization? " these have been classic arguments from Fortran programmers against C++ in numerics. The same goes for the intrinsic (core) array syntax introduced in Fortran90. So in this context, although standardization might be a weak argument it has been used strongly.The issue comes up now and then about why have complex and imaginary types, rather than using structs? All but one of the advantages of having them be core types can be addressed with advancing compiler technology. Getting rid of them will release 6 keywords, and make the core language simpler. Given the increasing complexity of D, this will help. The remaining advantage is that of imaginary literals, i.e. the i postfix: 3 + 5i Assuming we solve the literal problem, existing code would only need to add: import std.complex; to acquire complex and imaginary types.Hello all, although perhaps a bit late the following are my points of view. * Presumably D has a very interesting future in numerics. As you clearly state in the Foreword of the recently published 'Learn to Tango with D', there is a gaping hole. An moreover the need for performance and flexibility. Definitely, D is a much better way to tackle the increasing complexity of the next coming numerical projects. * There is no numerics in D without scientists and engineers programming it in D. In this numerical programming field, as in many other aspects of life, there is the classic approach and the more vanguardist one. In the classic and conservative branch people use the good old Fortran, perhaps recycled into Fortran95: "runs fast, it's easy to learn and we know it well". In the more vanguardist and progressive branch people use the hardcore C++: "here is where the real power is", perhaps a mixture of Python and Fortran. Probably formal education tends to be much less interdisciplinary than many of us wish it would be... The people from engineering dedicated to numerics know their fluid dynamics quite well, but in general the C++ not that well. The people from informatics dedicated to numerics know their C++ quite well, but in general the fluid dynamics not that well. All this is quite reasonable... both worlds are overly complex! fluid dynamics is the task, the programm* As Don said, game programmers might wonder why complex deserve to be in the core language and not quaternions. I agree, however that reasoning is due to the biased criterion of a game programmer. I would dare to say that the reasons why complex numbers are studied in any basic course of mathematics (along with integers and real numbers) and not the quaternions are the same as why they might be a better candidate to be in the core language.Yes, my comment wasn't really fair. Complex numbers are fundamental to mathematics in a way that quaternions are not. But, imagine if quaternions were included, and treated in the same way as cdouble/idouble. We'd need quaternions, imaginary, complex, real, root_i, i*root_i, (root_i+imaginary), (root_i+i*root_i), (imaginary+i*root_i), (root_i+imaginary+i*root_i). (real +root_i+imaginary), (real +root_i+i*root_i), (real + imaginary+i*root_i). That's 12 types * { float, double, real} = 36 types! It's just not a viable approach.* Again as Don said, the set of imaginary numbers has no practical use in mathematics. As Bill mentioned there is no set of the imaginary numbers defined in mathematics. Why should it be in a programming language? This would definitely strike a numerical analyst very weird! I think that if the type of complex numbers is in the core language it should respect the mathematical foundations, so why do we need the set of imaginary numbers? that definitely needs a redesign!Imaginary numbers were included in D because they are in C99. Why are they in C99? It's because of a really obscure situation. (a.re + a.im * 1i)*(0.0 + b.im * 1i) is not the same as (a.re + a.im * 1i)*(b.im * 1i) if a.im or a.re is infinity. In the version where b.re is 0.0, a NaN is created, instead of the correct answer of 0. Ultimately this happens because 0.0 can mean either exactly 0, or 'too small to represent' (an underflow).As far as I can tell, D can avoid the need for a pure imaginary type, because *D guarantees constant folding, whereas C does not*. If constant folding is guaranteed, then with any compile-time complex constant, you know if it is a zero, or just an underflow. The problematic multiply-by-approximately zero can be eliminated -- it is known that it is a multiply-by-exactly zero. So we don't need the C99 hack of creating an entirely different type.* Complex numbers are very useful in numerics. They may be used in many situations as if they were reals. They may reduce differential operations to algebraic ones: solving a linear set of differential equations in the real field reduces to solving a linear set of algebraic equations in the complex field. This is just to mention a few... I am not claiming this is an argument for complex numbers to be in the core language as long as performance holds the same. Well, i think that is about all i wanted to say... Cheers!
Jan 14 2008
Don Clugston wrote:Imaginary numbers were included in D because they are in C99. Why are they in C99? It's because of a really obscure situation. (a.re + a.im * 1i)*(0.0 + b.im * 1i) is not the same as (a.re + a.im * 1i)*(b.im * 1i) if a.im or a.re is infinity. In the version where b.re is 0.0, a NaN is created, instead of the correct answer of 0. Ultimately this happens because 0.0 can mean either exactly 0, or 'too small to represent' (an underflow).Thank you for the enlightening information.As far as I can tell, D can avoid the need for a pure imaginary type, because *D guarantees constant folding, whereas C does not*. If constant folding is guaranteed, then with any compile-time complex constant, you know if it is a zero, or just an underflow. The problematic multiply-by-approximately zero can be eliminated -- it is known that it is a multiply-by-exactly zero. So we don't need the C99 hack of creating an entirely different type.But since D doesn't guarantee inlining, I guess there would still be an issue with functions that today are overloaded for the imaginary types. -- Oskar
Jan 15 2008