digitalmars.D - proposed syntax change
- Paul D. Anderson (8/8) Aug 06 2009 I was browsing the Python spec yesterday and came across this interestin...
- bearophile (5/6) Aug 06 2009 Pascal uses the infix "div" operator.
- Michiel Helvensteijn (11/29) Aug 06 2009 Yeah, I love that distinction. As a matter of fact, I've added it to my ...
- Adam D. Ruppe (5/6) Aug 06 2009 Is this a joke?
- Ary Borenszweig (4/8) Aug 06 2009 No. When porting C, C++, Java or C# code just search "//" and replace it...
- Adam D. Ruppe (18/21) Aug 06 2009 Problem with this is old habit. I find myself annoyed with languages tha...
- Ary Borenszweig (3/26) Aug 06 2009 Aww... I intended to sound ironic. Didn't make it. :(
- language_fan (6/7) Aug 06 2009 The -- token may look too functional to many of us. I am pretty sure tha...
- ponce (2/2) Aug 06 2009 Same for me, it breaks compatibility with C.
- Paul D. Anderson (2/30) Aug 06 2009 Two words: "whoooooosh!"
- Adam D. Ruppe (6/8) Aug 06 2009 I have a hard enough time telling if someone is serious or not in real l...
- Paul D. Anderson (4/13) Aug 06 2009 Sorry -- I'd hoped I was being obtuse enough to make it obvious.
- Yigal Chripun (12/22) Aug 06 2009 Why would I as a user want to have two ops that do the same thing?!
- Robert Jacques (14/34) Aug 06 2009 No, it doesn't. (i.e. Welcome to the limitations of a context-free
- Jarrett Billingsley (4/9) Aug 06 2009 Uh, no. This has literally nothing to do with the grammar. What
- Robert Jacques (12/23) Aug 06 2009 I used the term context-free as the expression 5/2 must be evaluated fre...
- Yigal Chripun (14/61) Aug 07 2009 As you noted yourself, polysemous types help solve this and also the
- Robert Jacques (11/86) Aug 07 2009 No, I didn't. I just didn't have anything to say.
- Yigal Chripun (13/108) Aug 07 2009 Thanks for the info about the cast.
- Robert Jacques (11/117) Aug 07 2009 IIRC naked asm only works for zero-argument and single arguments of size...
- Sergey Gromov (6/27) Aug 07 2009 Inlined functions become integral part of their outer functions and
- Robert Jacques (7/37) Aug 07 2009 Yes and no. This is quite true for normal D functions, but throwing manu...
- Sergey Gromov (6/17) Aug 10 2009 Intrinsics were Yigal's point which he made twice:
- Jarrett Billingsley (16/22) Aug 06 2009 and useful syntax:
- Robert Fraser (11/18) Aug 06 2009 I like the idea of adding a "floating point division", but I think it
- Paul D. Anderson (3/25) Aug 06 2009 To the extent that this was a serious proposal (that is, to a very, very...
- Moritz Warning (7/34) Aug 06 2009 // has potential to be useful as an operator.
- Marianne Gagnon (2/10) Aug 06 2009 But, in your example it's still dependant on operand types. Division is ...
- Don (6/13) Aug 07 2009 Division of floats is also dependent on the rounding mode. There's
- Lars T. Kyllingstad (5/6) Aug 07 2009 I've been really missing that one.
- Daniel Keep (4/14) Aug 07 2009 How about *^
- Lars T. Kyllingstad (3/20) Aug 07 2009 Yeah, not too bad. Would a^^b work?
- Don (10/33) Aug 07 2009 Yes. I think it's the best option.
- bearophile (13/16) Aug 07 2009 I have asked for a power operator lot of time ago, in one of my first lo...
- Lars T. Kyllingstad (3/24) Aug 07 2009 This deserves its own thread. I'll create one.
- Pablo Ripolles (3/13) Aug 08 2009 Why a**b is out the question?
- Pablo Ripolles (2/20) Aug 08 2009 :) ok, I see now!
I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution. It seems to me that this could be added to D with very little effort and would add a feature to the language. Oh wait...I think "//" is used elsewhere. Well, we could still use it but mark it as a breaking change. Then users could simply remove all previous uses of "//" from their code. If they REALLY need to retain the old "//" functionality we could replace it with a new symbol. How about "--", like Ada? Oh wait... I will also throw out (at no cost) a suggestion for the Python people: Why not make "/%" the divmod operator (returning the quotient and remainder)? It would return a tuple, but Python is used to that. Paul
Aug 06 2009
Paul D. Anderson:Oh wait...I think "//" is used elsewhere. Well, we could still use it but mark it as a breaking change. Then users could simply remove all previous uses of "//" from their code. If they REALLY need to retain the old "//" functionality we could replace it with a new symbol. How about "--", like Ada? Oh wait...Pascal uses the infix "div" operator. In OcalML operators among FPs are followed by a dot. Bye, bearophile
Aug 06 2009
Paul D. Anderson wrote:I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats.Yeah, I love that distinction. As a matter of fact, I've added it to my own language. Same syntax, too, though there was some thought about using the "div" keyword instead.I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution.I agree. It's one of those C idiosyncrasies the world could do without.It seems to me that this could be added to D with very little effort and would add a feature to the language.Seems like trouble to me. If we ignore for the moment the fact that "//" is used for line comments (D could use "div", for example), changing the meaning of "/" for integer operands would probably break many programs.Oh wait...I think "//" is used elsewhere. Well, we could still use it but mark it as a breaking change. Then users could simply remove all previous uses of "//" from their code. If they REALLY need to retain the old "//" functionality we could replace it with a new symbol. How about "--", like Ada? Oh wait...Line-comments are very useful. My language uses "|". -- Michiel Helvensteijn
Aug 06 2009
On Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:Oh wait...I think "//" is used elsewhere.Is this a joke? -- Adam D. Ruppe http://arsdnet.net
Aug 06 2009
Adam D. Ruppe wrote:On Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?
Aug 06 2009
On Thu, Aug 06, 2009 at 04:35:41PM -0300, Ary Borenszweig wrote:with "--".Problem with this is old habit. I find myself annoyed with languages that don't accept // comments just because I'm so used to typing them that it is my first instinct to comment a line. Doing a find and replace of // with something else is fairly simple (it isn't trivial, since "//" != "--" even if // == --, but that's not too hard to work with), but retraining fingers to type something new is a pain to do.Oh wait... I think "--" is used elsewhere.Secondly, as to why I asked if it was a joke: how can someone use D or C++ and not know that // already has a meaning? I find it very hard to believe that someone can have any real world experience in the language at all and not know that // is in use. If you don't have any real world experience in the language, or at least in its direct predecessor (C++), what business do you have proposing breaking changes to it? -- Adam D. Ruppe http://arsdnet.net
Aug 06 2009
Adam D. Ruppe wrote:On Thu, Aug 06, 2009 at 04:35:41PM -0300, Ary Borenszweig wrote:Aww... I intended to sound ironic. Didn't make it. :( Of course I think using "//" for something else is a disaster.with "--".Problem with this is old habit. I find myself annoyed with languages that don't accept // comments just because I'm so used to typing them that it is my first instinct to comment a line. Doing a find and replace of // with something else is fairly simple (it isn't trivial, since "//" != "--" even if // == --, but that's not too hard to work with), but retraining fingers to type something new is a pain to do.Oh wait... I think "--" is used elsewhere.Secondly, as to why I asked if it was a joke: how can someone use D or C++ and not know that // already has a meaning? I find it very hard to believe that someone can have any real world experience in the language at all and not know that // is in use. If you don't have any real world experience in the language, or at least in its direct predecessor (C++), what business do you have proposing breaking changes to it?
Aug 06 2009
Thu, 06 Aug 2009 17:06:40 -0300, Ary Borenszweig thusly wrote:Of course I think using "//" for something else is a disaster.The -- token may look too functional to many of us. I am pretty sure that a great deal of D users would choose a buggy, badly optimizing compiler and an incomplete spec over a perfectly working D 3.0 compiler and spec if the latter one used -- for one line comments. It's a serious step towards unknown if you try to stay compatible with C.
Aug 06 2009
Same for me, it breaks compatibility with C. Also, i found the ocaml floating point operators (./ .+ .- .*) painful when i had to use them.
Aug 06 2009
Adam D. Ruppe Wrote:On Thu, Aug 06, 2009 at 04:35:41PM -0300, Ary Borenszweig wrote:Two words: "whoooooosh!"with "--".Problem with this is old habit. I find myself annoyed with languages that don't accept // comments just because I'm so used to typing them that it is my first instinct to comment a line. Doing a find and replace of // with something else is fairly simple (it isn't trivial, since "//" != "--" even if // == --, but that's not too hard to work with), but retraining fingers to type something new is a pain to do.Oh wait... I think "--" is used elsewhere.Secondly, as to why I asked if it was a joke: how can someone use D or C++ and not know that // already has a meaning? I find it very hard to believe that someone can have any real world experience in the language at all and not know that // is in use. If you don't have any real world experience in the language, or at least in its direct predecessor (C++), what business do you have proposing breaking changes to it? -- Adam D. Ruppe http://arsdnet.net
Aug 06 2009
On Thu, Aug 06, 2009 at 04:48:40PM -0400, Paul D. Anderson wrote:Two words: "whoooooosh!"I have a hard enough time telling if someone is serious or not in real life; it is even harder in plain text :S -- Adam D. Ruppe http://arsdnet.net
Aug 06 2009
Adam D. Ruppe Wrote:On Thu, Aug 06, 2009 at 04:48:40PM -0400, Paul D. Anderson wrote:Sorry -- I'd hoped I was being obtuse enough to make it obvious. I will admit (quietly) that when I first saw the // operator I really did think it might be a good idea for D. But only for a second or so. And even then I didn't realize changing the meaning of / would also break a lot of code. PaulTwo words: "whoooooosh!"I have a hard enough time telling if someone is serious or not in real life; it is even harder in plain text :S -- Adam D. Ruppe http://arsdnet.net
Aug 06 2009
Ary Borenszweig wrote:Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer division auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer division auto d = floor(5 / 2); // FP division floored by a function to int auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?On Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?
Aug 06 2009
On Thu, 06 Aug 2009 13:34:21 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Ary Borenszweig wrote:No, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer divisionOn Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:it with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer divisionNo, the cast would apply to the result of (5/2), not the '/' operator.auto d = floor(5 / 2); // FP division floored by a function to intfloor returns a real, not an int. I think you were looking for roundTo!int or roundTo!int(floor(5/2))auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?The rationale is that integer division is very common and is usually assigned back into an int, and not a real. The only issue is literals, which were going to be handled with polysemous values (but that got dropped). But 2/5.0 is really not that much overhead.
Aug 06 2009
On Thu, Aug 6, 2009 at 6:02 PM, Robert Jacques<sandford jhu.edu> wrote:Uh, no. This has literally nothing to do with the grammar. What happens in this line would be determined in the semantic phase, not parsing.int a = 5 / 2; // compiler knows to use integer divisionNo, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.
Aug 06 2009
On Thu, 06 Aug 2009 15:10:27 -0700, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Thu, Aug 6, 2009 at 6:02 PM, Robert Jacques<sandford jhu.edu> wrote:I used the term context-free as the expression 5/2 must be evaluated free of its context: i.e. 'int a =' or 'real b ='. I apologise if this is an over generalization of the term (it's been too long since my algorithm's class) But the rest of my comment is valid. This came up before while looking at how 'long = int + int' should be evaluated with regard to overflow. Walter explained that currently in DMD, 'int+int' or in this case '5/2' gets evaluated before the assignment statement, so it doesn't know/can't use the type information of the assignment. As I said polysemous values fixes this, but they are rather computationally expensive to support.Uh, no. This has literally nothing to do with the grammar. What happens in this line would be determined in the semantic phase, not parsing.int a = 5 / 2; // compiler knows to use integer divisionNo, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.
Aug 06 2009
Robert Jacques wrote:On Thu, 06 Aug 2009 13:34:21 -0700, Yigal Chripun <yigal100 gmail.com> wrote:As you noted yourself, polysemous types help solve this and also the compiler can have special handling (peep hole optimizations) for some of the above cases. in case D roundTo sounds indeed better (and since in the above it's compile time, it should be possible to optimize it. you've ignored case f which seems to me the most important: instead of currently 5/2 == 2 there should be a div intristic function such that div(5, 2) == 2 and that intristic will be the appropriate ASM instruction for integer division. In general, you can always round down a float but you can't get the correct double out of the rounded int, so my question is how much a performance hit is it to use the FP as default and only use the div intristic where performance is really an issue?Ary Borenszweig wrote:No, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer divisionOn Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:replace it with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer divisionNo, the cast would apply to the result of (5/2), not the '/' operator.auto d = floor(5 / 2); // FP division floored by a function to intfloor returns a real, not an int. I think you were looking for roundTo!int or roundTo!int(floor(5/2))auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?The rationale is that integer division is very common and is usually assigned back into an int, and not a real. The only issue is literals, which were going to be handled with polysemous values (but that got dropped). But 2/5.0 is really not that much overhead.
Aug 07 2009
On Fri, 07 Aug 2009 01:22:31 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Robert Jacques wrote:No, I didn't. I just didn't have anything to say.On Thu, 06 Aug 2009 13:34:21 -0700, Yigal Chripun <yigal100 gmail.com> wrote:As you noted yourself, polysemous types help solve this and also the compiler can have special handling (peep hole optimizations) for some of the above cases. in case D roundTo sounds indeed better (and since in the above it's compile time, it should be possible to optimize it. you've ignored case f which seems to me the most important: instead of currently 5/2 == 2 there should be a div intristic function such that div(5, 2) == 2 and that intristic will be the appropriate ASM instruction for integer division.Ary Borenszweig wrote:No, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer divisionOn Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:replace it with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer divisionNo, the cast would apply to the result of (5/2), not the '/' operator.auto d = floor(5 / 2); // FP division floored by a function to intfloor returns a real, not an int. I think you were looking for roundTo!int or roundTo!int(floor(5/2))auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?The rationale is that integer division is very common and is usually assigned back into an int, and not a real. The only issue is literals, which were going to be handled with polysemous values (but that got dropped). But 2/5.0 is really not that much overhead.In general, you can always round down a float but you can't get the correct double out of the rounded int, so my question is how much a performance hit is it to use the FP as default and only use the div intristic where performance is really an issue?Now that I think about it, turning integer division into a function is a really bad idea: 1) there's function call overhead and 2) even if inlined, register values and the stack still have to be manipulated (as function call syntax dictates where the inputs and outputs are located) Today, DMD can choose any set of register inputs and outputs. As for the int-float conversion, apperently float-int is somewhat slow and destroys the floating point pipeline From http://mega-nerd.com/FPcast/The instruction which causes the real damage in this block is fldcw, (FPU load control word) on lines 8 and 11. Whenever the FPU encounters this instruction it flushes its pipeline and loads the control word before continuing operation. The FPUs of modern CPUs like the Pentium III, Pentium IV and AMD Athlons rely on deep pipelines to achieve higher peak performance. Unfortunately certain pieces of C code can reduce the floating point performance of the CPU to level of a non-pipelined FPU.So why is the fldcw instruction used? Unfortunately, it is required to make the calculation meet the ISO C Standard which specifies that casting from floating point to integer is a truncation operation. However, if the fistpl instruction was executed without changing the mode of the FPU, the value would have been rounded instead of truncated. The standard rounding mode is required for all normal operations like addition, subtraction, multiplication etc while truncation mode is required for the float to int cast. Hence if a block of code contains a float to int cast, the FPU will spend a large amount of its time switching between the two modes.
Aug 07 2009
Robert Jacques wrote:On Fri, 07 Aug 2009 01:22:31 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Thanks for the info about the cast. regarding the div() function above, I was thinking about using D's naked asm feature. From what little I know about this, the compiler doesn't generate the usual asm code for this sort of function to handle registers, stack, etc, and you're supposed to do everything yourself in asm. I don't think your comment above about the function call overhead applies if div is implemented in such a way but I'm no expert and someone more knowledgeable can shed more light on this. (Don?) also, div can be implemented in the compiler in the same way c++ style casts have template syntax ( e.g. static_cast<whatever>(thing) ) but are implemented inside the compiler.Robert Jacques wrote:No, I didn't. I just didn't have anything to say.On Thu, 06 Aug 2009 13:34:21 -0700, Yigal Chripun <yigal100 gmail.com> wrote:As you noted yourself, polysemous types help solve this and also the compiler can have special handling (peep hole optimizations) for some of the above cases. in case D roundTo sounds indeed better (and since in the above it's compile time, it should be possible to optimize it. you've ignored case f which seems to me the most important: instead of currently 5/2 == 2 there should be a div intristic function such that div(5, 2) == 2 and that intristic will be the appropriate ASM instruction for integer division.Ary Borenszweig wrote:No, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer divisionOn Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:replace it with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer divisionNo, the cast would apply to the result of (5/2), not the '/' operator.auto d = floor(5 / 2); // FP division floored by a function to intfloor returns a real, not an int. I think you were looking for roundTo!int or roundTo!int(floor(5/2))auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?The rationale is that integer division is very common and is usually assigned back into an int, and not a real. The only issue is literals, which were going to be handled with polysemous values (but that got dropped). But 2/5.0 is really not that much overhead.In general, you can always round down a float but you can't get the correct double out of the rounded int, so my question is how much a performance hit is it to use the FP as default and only use the div intristic where performance is really an issue?Now that I think about it, turning integer division into a function is a really bad idea: 1) there's function call overhead and 2) even if inlined, register values and the stack still have to be manipulated (as function call syntax dictates where the inputs and outputs are located) Today, DMD can choose any set of register inputs and outputs. As for the int-float conversion, apperently float-int is somewhat slow and destroys the floating point pipeline From http://mega-nerd.com/FPcast/The instruction which causes the real damage in this block is fldcw, (FPU load control word) on lines 8 and 11. Whenever the FPU encounters this instruction it flushes its pipeline and loads the control word before continuing operation. The FPUs of modern CPUs like the Pentium III, Pentium IV and AMD Athlons rely on deep pipelines to achieve higher peak performance. Unfortunately certain pieces of C code can reduce the floating point performance of the CPU to level of a non-pipelined FPU.So why is the fldcw instruction used? Unfortunately, it is required to make the calculation meet the ISO C Standard which specifies that casting from floating point to integer is a truncation operation. However, if the fistpl instruction was executed without changing the mode of the FPU, the value would have been rounded instead of truncated. The standard rounding mode is required for all normal operations like addition, subtraction, multiplication etc while truncation mode is required for the float to int cast. Hence if a block of code contains a float to int cast, the FPU will spend a large amount of its time switching between the two modes.
Aug 07 2009
On Fri, 07 Aug 2009 12:03:43 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Robert Jacques wrote:IIRC naked asm only works for zero-argument and single arguments of size 1,2 or 4 functions, which div is not.On Fri, 07 Aug 2009 01:22:31 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Thanks for the info about the cast. regarding the div() function above, I was thinking about using D's naked asm feature. From what little I know about this, the compiler doesn't generate the usual asm code for this sort of function to handle registers, stack, etc, and you're supposed to do everything yourself in asm.Robert Jacques wrote:No, I didn't. I just didn't have anything to say.On Thu, 06 Aug 2009 13:34:21 -0700, Yigal Chripun <yigal100 gmail.com> wrote:As you noted yourself, polysemous types help solve this and also the compiler can have special handling (peep hole optimizations) for some of the above cases. in case D roundTo sounds indeed better (and since in the above it's compile time, it should be possible to optimize it. you've ignored case f which seems to me the most important: instead of currently 5/2 == 2 there should be a div intristic function such that div(5, 2) == 2 and that intristic will be the appropriate ASM instruction for integer division.Ary Borenszweig wrote:No, it doesn't. (i.e. Welcome to the limitations of a context-free grammar) The right hand of the expression has to be evaluated before the left, or otherwise function overloads, etc, don't work, so there's no way for the compiler to know the type of the expected result when 5/2 is evaluated.Adam D. Ruppe wrote:Why would I as a user want to have two ops that do the same thing?! Python's solution for this is wrong IMHO since the problem is not with the op itself but rather with the way C handles numbers. 5 / 2 should always be the more precise FP division unless the compiler knows or is instructed to do otherwise. int a = 5 / 2; // compiler knows to use integer divisionOn Thu, Aug 06, 2009 at 03:06:49PM -0400, Paul D. Anderson wrote:replace it with "--". Oh wait... I think "--" is used elsewhere.Oh wait...I think "//" is used elsewhere.Is this a joke?auto b = 5 / 2; // b is double, FP division auto c = cast(int)(5/2)); // compiler instructed to use integer divisionNo, the cast would apply to the result of (5/2), not the '/' operator.auto d = floor(5 / 2); // FP division floored by a function to intfloor returns a real, not an int. I think you were looking for roundTo!int or roundTo!int(floor(5/2))auto f = std.math.div(5, 2); // intristic that does integer division what's the rationale of not doing the above, besides C compatibility?The rationale is that integer division is very common and is usually assigned back into an int, and not a real. The only issue is literals, which were going to be handled with polysemous values (but that got dropped). But 2/5.0 is really not that much overhead.In general, you can always round down a float but you can't get the correct double out of the rounded int, so my question is how much a performance hit is it to use the FP as default and only use the div intristic where performance is really an issue?Now that I think about it, turning integer division into a function is a really bad idea: 1) there's function call overhead and 2) even if inlined, register values and the stack still have to be manipulated (as function call syntax dictates where the inputs and outputs are located) Today, DMD can choose any set of register inputs and outputs. As for the int-float conversion, apperently float-int is somewhat slow and destroys the floating point pipeline From http://mega-nerd.com/FPcast/The instruction which causes the real damage in this block is fldcw, (FPU load control word) on lines 8 and 11. Whenever the FPU encounters this instruction it flushes its pipeline and loads the control word before continuing operation. The FPUs of modern CPUs like the Pentium III, Pentium IV and AMD Athlons rely on deep pipelines to achieve higher peak performance. Unfortunately certain pieces of C code can reduce the floating point performance of the CPU to level of a non-pipelined FPU.So why is the fldcw instruction used? Unfortunately, it is required to make the calculation meet the ISO C Standard which specifies that casting from floating point to integer is a truncation operation. However, if the fistpl instruction was executed without changing the mode of the FPU, the value would have been rounded instead of truncated. The standard rounding mode is required for all normal operations like addition, subtraction, multiplication etc while truncation mode is required for the float to int cast. Hence if a block of code contains a float to int cast, the FPU will spend a large amount of its time switching between the two modes.I don't think your comment above about the function call overhead applies if div is implemented in such a way but I'm no expert and someone more knowledgeable can shed more light on this. (Don?)If you check the D ABI, one of the arguments must be passed on the stack, the other in a specific register (EAX). http://www.digitalmars.com/d/2.0/abi.html So the backend can't do things like ECX = EBX / EDX. Instead it has to save/restore whatever's in EAX, ECX and EDX before/after the div call.also, div can be implemented in the compiler in the same way c++ style casts have template syntax ( e.g. static_cast<whatever>(thing) ) but are implemented inside the compiler.Well, technically, static cast isn't a function. Also, div should live in std.object and not std.math.
Aug 07 2009
Fri, 07 Aug 2009 13:47:31 -0700, Robert Jacques wrote:On Fri, 07 Aug 2009 12:03:43 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Inlined functions become integral part of their outer functions and therefore are not obliged to follow ABI. They don't have prologues, epilogues, call overhead, etc. Moreover compiler intrinsics are functions which compiler recognizes and treats specially, usually by replacing them with a single processor instruction.regarding the div() function above, I was thinking about using D's naked asm feature. From what little I know about this, the compiler doesn't generate the usual asm code for this sort of function to handle registers, stack, etc, and you're supposed to do everything yourself in asm.IIRC naked asm only works for zero-argument and single arguments of size 1,2 or 4 functions, which div is not.I don't think your comment above about the function call overhead applies if div is implemented in such a way but I'm no expert and someone more knowledgeable can shed more light on this. (Don?)If you check the D ABI, one of the arguments must be passed on the stack, the other in a specific register (EAX). http://www.digitalmars.com/d/2.0/abi.html So the backend can't do things like ECX = EBX / EDX. Instead it has to save/restore whatever's in EAX, ECX and EDX before/after the div call.
Aug 07 2009
On Fri, 07 Aug 2009 15:44:04 -0700, Sergey Gromov <snake.scaly gmail.com> wrote:Fri, 07 Aug 2009 13:47:31 -0700, Robert Jacques wrote:Yes and no. This is quite true for normal D functions, but throwing manual asm into the mix does mess up register allocation, etc. Even with naked asm, a minimum three registers must be saved.On Fri, 07 Aug 2009 12:03:43 -0700, Yigal Chripun <yigal100 gmail.com> wrote:Inlined functions become integral part of their outer functions and therefore are not obliged to follow ABI. They don't have prologues, epilogues, call overhead, etc.regarding the div() function above, I was thinking about using D's naked asm feature. From what little I know about this, the compiler doesn't generate the usual asm code for this sort of function to handle registers, stack, etc, and you're supposed to do everything yourself in asm.IIRC naked asm only works for zero-argument and single arguments of size 1,2 or 4 functions, which div is not.I don't think your comment above about the function call overhead applies if div is implemented in such a way but I'm no expert and someone more knowledgeable can shed more light on this. (Don?)If you check the D ABI, one of the arguments must be passed on the stack, the other in a specific register (EAX). http://www.digitalmars.com/d/2.0/abi.html So the backend can't do things like ECX = EBX / EDX. Instead it has to save/restore whatever's in EAX, ECX and EDX before/after the div call.Moreover compiler intrinsics are functions which compiler recognizes and treats specially, usually by replacing them with a single processor instruction.We weren't discussing implementation with intrinsics, but as with a standard library function.
Aug 07 2009
Fri, 07 Aug 2009 17:02:33 -0700, Robert Jacques wrote:Intrinsics were Yigal's point which he made twice: Thu, 06 Aug 2009 23:34:21 +0300, Yigal Chripun wrote:Moreover compiler intrinsics are functions which compiler recognizes and treats specially, usually by replacing them with a single processor instruction.We weren't discussing implementation with intrinsics, but as with a standard library function.auto f = std.math.div(5, 2); // intristic that does integer divisionFri, 07 Aug 2009 11:22:31 +0300, Yigal Chripun wrote:you've ignored case f which seems to me the most important: instead of currently 5/2 == 2 there should be a div intristic function such that div(5, 2) == 2 and that intristic will be the appropriate ASM instruction for integer division.Well, he called them "intristics," bit it's easy to see what he actually wanted to say.
Aug 10 2009
On Thu, Aug 6, 2009 at 3:06 PM, Paul D. Anderson<paul.d.removethis.anderson comcast.andthis.net> wrote:I was browsing the Python spec yesterday and came across this interesting=and useful syntax:"/" (one slash) means floating point division, e.g. 5/2 =3D 2.5 even thou=gh 5 and 2 are integers"//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 =3D 2.0 =even though 5.0 and 2.0 are floats.I've always been a little troubled by the standard division operator bein=g dependent on the types of the operands. (I understand the need for it, I = just didn't like it much.) Now here is an elegant (IMHO) solution.It seems to me that this could be added to D with very little effort and =would add a feature to the language. *snort* Nevermind breaking *all comments ever written*. Yes, it would add a feature to the language. Lots of things would. Thanks for stating the obvious.Oh wait...I think "//" is used elsewhere. Well, we could still use it but=mark it as a breaking change. Then users could simply remove all previous = uses of "//" from their code. If they REALLY need to retain the old "//" fu= nctionality we could replace it with a new symbol. How about "--", like Ada= ? Oh wait... It's at this point I really think you're joking.
Aug 06 2009
Paul D. Anderson wrote:I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution.I like the idea of adding a "floating point division", but I think it should be a *new* feature while the current / and // are left as they are. How about "./"? 5 / 2 = 2 // Current behavior 5.0 / 2.0 = 2.5 // Current behavior 5 ./ 2 = 2.5 // New behavior 5.0 ./ 2.0 = 2.5 // It always floating-point divides IOW, ./ is short for "cast operands to double and divide". If ./ proves too hard to parse (I think it might require some lookahead), then /^ might work.
Aug 06 2009
Robert Fraser Wrote:Paul D. Anderson wrote:To the extent that this was a serious proposal (that is, to a very, very small extent) I would rather reserve the ./ operator for element-wise array division, along with .*, etc., since I'm used to that in other languages. (And the whole point of proposing syntax is to make one's own self comfortable, right?) PaulI was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution.I like the idea of adding a "floating point division", but I think it should be a *new* feature while the current / and // are left as they are. How about "./"? 5 / 2 = 2 // Current behavior 5.0 / 2.0 = 2.5 // Current behavior 5 ./ 2 = 2.5 // New behavior 5.0 ./ 2.0 = 2.5 // It always floating-point divides IOW, ./ is short for "cast operands to double and divide". If ./ proves too hard to parse (I think it might require some lookahead), then /^ might work.
Aug 06 2009
On Thu, 06 Aug 2009 15:06:49 -0400, Paul D. Anderson wrote:I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution. It seems to me that this could be added to D with very little effort and would add a feature to the language. Oh wait...I think "//" is used elsewhere. Well, we could still use it but mark it as a breaking change. Then users could simply remove all previous uses of "//" from their code. If they REALLY need to retain the old "//" functionality we could replace it with a new symbol. How about "--", like Ada? Oh wait... I will also throw out (at no cost) a suggestion for the Python people: Why not make "/%" the divmod operator (returning the quotient and remainder)? It would return a tuple, but Python is used to that. Paul// has potential to be useful as an operator. Easier to type, used as comment in other languages and no apparent use as operator. Imho, for D, to change the meaning for // might be too much of a breaking change.
Aug 06 2009
Paul D. Anderson Wrote:I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution.But, in your example it's still dependant on operand types. Division is performed very differently on integers and on IEEE754 floats. So even with your proposal there would be implicit casts. Also you give example 5.0//2.0 = 2.0. Isn't // integer division? But it gives a truncated float? Oh, still more type inference.
Aug 06 2009
Paul D. Anderson wrote:I was browsing the Python spec yesterday and came across this interesting and useful syntax: "/" (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers "//" (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands.Division of floats is also dependent on the rounding mode. There's actually no unabiguous "floating point division". float f = ulong.max / 2.0; Can't be represented exactly in a float, so it has to perform rounding. The operator which is REALLY missing is exponentiation.
Aug 07 2009
Don wrote:The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 07 2009
Lars T. Kyllingstad wrote:Don wrote:How about *^ ^ isn't valid as a unary operator, thus a*^b cannot be mistaken for a*(^b) It's a bit of a cop-out combining the two, but should be unambiguous.The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 07 2009
Daniel Keep wrote:Lars T. Kyllingstad wrote:Yeah, not too bad. Would a^^b work? -LarsDon wrote:How about *^ ^ isn't valid as a unary operator, thus a*^b cannot be mistaken for a*(^b) It's a bit of a cop-out combining the two, but should be unambiguous.The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 07 2009
Lars T. Kyllingstad wrote:Daniel Keep wrote:Yes. I think it's the best option. Note that we already have the table: bitwise logical & && | || ^ != so there's nothing else you'd want to use ^^ for. People would get used to it pretty quickly. I think it looks better than Fortran's **, actually. double y = x^^2;Lars T. Kyllingstad wrote:Yeah, not too bad. Would a^^b work? -LarsDon wrote:How about *^ ^ isn't valid as a unary operator, thus a*^b cannot be mistaken for a*(^b) It's a bit of a cop-out combining the two, but should be unambiguous.The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 07 2009
Don:so there's nothing else you'd want to use ^^ for. People would get used to it pretty quickly. I think it looks better than Fortran's **, actually. double y = x^^2;I have asked for a power operator lot of time ago, in one of my first long lists of suggestions. ^^ isn't standard in other languages (they usually use ** or ^), but it looks nice enough, and it doesn't look hard to understand or learn. I'd like it to perform integral exponentiation if both operands are integral, and double/real exponentiation in the other cases. In mathematics ^^ is sometimes used for Tetration, but it's not a problem, it's not a common operation: http://en.wikipedia.org/wiki/Tetration So this looks like a good idea. The front-end *must* be able to translate x ^^ 2 and x ^^ 3 into x*x and x*x*x, that are faster than any other kind of operation (Python doesn't do this simple operation, and a power operation done in the middle of a critical loop can slow down the code, I have seen this in my Python code). (x ^^ 4 can be simplified into y = x*x; y*y, but this is a less common operation). I guess the way to overload this operator is named opPower(). So for example if A is a user-defined matrix you can write: auto B = A ^^ 2; Bye, bearophile
Aug 07 2009
bearophile wrote:Don:This deserves its own thread. I'll create one. -Larsso there's nothing else you'd want to use ^^ for. People would get used to it pretty quickly. I think it looks better than Fortran's **, actually. double y = x^^2;I have asked for a power operator lot of time ago, in one of my first long lists of suggestions. ^^ isn't standard in other languages (they usually use ** or ^), but it looks nice enough, and it doesn't look hard to understand or learn. I'd like it to perform integral exponentiation if both operands are integral, and double/real exponentiation in the other cases. In mathematics ^^ is sometimes used for Tetration, but it's not a problem, it's not a common operation: http://en.wikipedia.org/wiki/Tetration So this looks like a good idea. The front-end *must* be able to translate x ^^ 2 and x ^^ 3 into x*x and x*x*x, that are faster than any other kind of operation (Python doesn't do this simple operation, and a power operation done in the middle of a critical loop can slow down the code, I have seen this in my Python code). (x ^^ 4 can be simplified into y = x*x; y*y, but this is a less common operation). I guess the way to overload this operator is named opPower(). So for example if A is a user-defined matrix you can write: auto B = A ^^ 2; Bye, bearophile
Aug 07 2009
Lars T. Kyllingstad Wrote:Don wrote:Why a**b is out the question? Thanks!The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 08 2009
Pablo Ripolles Wrote:Lars T. Kyllingstad Wrote::) ok, I see now!Don wrote:Why a**b is out the question? Thanks!The operator which is REALLY missing is exponentiation.I've been really missing that one. Which operators could be used for exponentiation? I've only ever seen a**b and a^b used, but I think those are out of the question for D. -Lars
Aug 08 2009