digitalmars.D.learn - Stride
- RenatoL (14/14) Feb 12 2012 Loosing my time on skittles...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (11/25) Feb 12 2012 This is yet another problem caused by the dual nature of narrow strings....
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/34) Feb 12 2012 No matter how much *my* explanation below still makes sense to *me*, :p
- RenatoL (9/9) Feb 12 2012 This is the code i compiled v. 2057 and parameters 0 1
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/16) Feb 12 2012 Argh! std.algorithm.stride() and std.utf.stride() are different. :) What...
- RenatoL (10/10) Feb 12 2012 Mmmm.... this doesn't compile....
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (5/15) Feb 12 2012 Because I am not operating correctly lately. :(
- Jonathan M Davis (5/11) Feb 13 2012 It's currently unspecified. Walter has stated that he wants to make it s...
- Artur Skawina (5/16) Feb 13 2012 Actually, it *is* specified as left-to-right, except for assignments and...
- Jonathan M Davis (5/22) Feb 13 2012 Well, foo() ~ bar() _is_ argument evaluation if you're dealing with an
- Artur Skawina (9/31) Feb 13 2012 "argument evaluation" in this context means that given eg "f(a,b,c);"
- Jonathan M Davis (13/20) Feb 13 2012 Ideally perhaps, but I expect that that's not true, because operator
- Daniel Murphy (7/12) Feb 14 2012 While your point is still correct, this will generally be lowered to
- Jonathan M Davis (3/24) Feb 14 2012 Ah, good point.
- Artur Skawina (15/40) Feb 13 2012 The important thing here is - the order absolutely *must* be foo(), then...
- Jonathan M Davis (10/23) Feb 13 2012 I'm not arguing that the order _shouldn't_ be defined and guaranteed. I'...
- Artur Skawina (12/28) Feb 13 2012 I'm not arguing that it _should_ be defined - just pointing out that the...
- Timon Gehr (14/42) Feb 13 2012 D the language requires L-T-R for both binary operators and function
- Artur Skawina (10/43) Feb 13 2012 In theory it shouldn't, but it's much better to have a situation where t...
- RenatoL (9/9) Feb 14 2012 mmmhhh.... this is interesting nevertheless i don't understand the
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (14/23) Feb 14 2012 import std.stdio;
- Chris W. (20/47) Mar 14 2012 I have come across similar problems using stride.
- Jonathan M Davis (13/24) Feb 13 2012 The reality of the matter is that the spec is untrustworthy. The compile...
Loosing my time on skittles... input "abcd" desired output "arcd" i want to use stride snippet, where x and y are integer in real code: string s1 = "abcd"; s1 = s1[stride(s1,x)..y] ~ 'r' ~ s1[2..$]; if x = 0 and y = 0 -> run time error. ok if x = 0 and y = 1 -> "rcd" (??) if x = 1 and y = 0 -> run time error. ok if x = 1 and y = 1 -> "rcd" if x = 0 and y = 2 -> "brcd" (WTF?) if x = 1 and y = 2 -> "brcd" (...) what the hell of parameters have i to put to achieve "arcd"?
Feb 12 2012
On 02/12/2012 09:37 AM, RenatoL wrote:Loosing my time on skittles... input "abcd" desired output "arcd" i want to use stride snippet, where x and y are integer in real code: string s1 = "abcd"; s1 = s1[stride(s1,x)..y] ~ 'r' ~ s1[2..$]; if x = 0 and y = 0 -> run time error. ok if x = 0 and y = 1 -> "rcd" (??) if x = 1 and y = 0 -> run time error. ok if x = 1 and y = 1 -> "rcd" if x = 0 and y = 2 -> "brcd" (WTF?) if x = 1 and y = 2 -> "brcd" (...) what the hell of parameters have i to put to achieve "arcd"?This is yet another problem caused by the dual nature of narrow strings. When used with algorithms like stride(), a char[] is *not* a RandomAccessRange but when used with the [] operator it is. According the stride()'s documentation, s1 will lose elements through popFront() because of not being a RandomAccessRange. Related question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++? Ali
Feb 12 2012
On 02/12/2012 10:07 AM, Ali Çehreli wrote:On 02/12/2012 09:37 AM, RenatoL wrote: > Loosing my time on skittles... > > input "abcd" > desired output "arcd" > i want to use stride > > snippet, where x and y are integer in real code: > > string s1 = "abcd"; > s1 = s1[stride(s1,x)..y] ~ 'r' ~ s1[2..$];No matter how much *my* explanation below still makes sense to *me*, :p I can't compile that code with dmd 2.057. (?)> > if x = 0 and y = 0 -> run time error. ok > if x = 0 and y = 1 -> "rcd" (??) > if x = 1 and y = 0 -> run time error. ok > if x = 1 and y = 1 -> "rcd" > if x = 0 and y = 2 -> "brcd" (WTF?) > if x = 1 and y = 2 -> "brcd" (...) > > what the hell of parameters have i to put to achieve "arcd"? This is yet another problem caused by the dual nature of narrow strings. When used with algorithms like stride(), a char[] is *not* a RandomAccessRange but when used with the [] operator it is. According the stride()'s documentation, s1 will lose elements through popFront() because of not being a RandomAccessRange. Related question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++? AliAli
Feb 12 2012
This is the code i compiled v. 2057 and parameters 0 1 import std.stdio; import std.utf; void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); }
Feb 12 2012
On 02/12/2012 10:25 AM, RenatoL wrote:This is the code i compiled v. 2057 and parameters 0 1 import std.stdio; import std.utf; void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); }Argh! std.algorithm.stride() and std.utf.stride() are different. :) What a confusion! :( I think the following is correct for the first part, but the 2 in the last part will also be wrong unless it is also calculated: s1 = s1[0..stride(s1,0)] ~ 'r' ~ s1[2..$]; Ali
Feb 12 2012
Mmmm.... this doesn't compile.... import std.stdio; import std.algorithm; void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); } Error: undefined identifier stride, did you mean alias string?
Feb 12 2012
On 02/12/2012 11:05 AM, RenatoL wrote:Mmmm.... this doesn't compile.... import std.stdio; import std.algorithm; void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); } Error: undefined identifier stride, did you mean alias string?Because I am not operating correctly lately. :( I meant std.range, not std.algorithm. But std.range.stride will cause a different compilation error because it returns a range object, not an index. Ali
Feb 12 2012
On Sunday, February 12, 2012 10:07:52 Ali Çehreli wrote:Related question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++?It's currently unspecified. Walter has stated that he wants to make it so that it's always left to right, but I don't believe that he's done it yet, and it may or may not ever happen. - Jonathan m Davis
Feb 13 2012
On 02/13/12 18:57, Jonathan M Davis wrote:On Sunday, February 12, 2012 10:07:52 Ali Çehreli wrote:Actually, it *is* specified as left-to-right, except for assignments and argument evaluation. http://dlang.org/expression.html No idea if the compiler fully implements that part of the spec. arturRelated question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++?It's currently unspecified. Walter has stated that he wants to make it so that it's always left to right, but I don't believe that he's done it yet, and it may or may not ever happen.
Feb 13 2012
On Monday, February 13, 2012 19:47:03 Artur Skawina wrote:On 02/13/12 18:57, Jonathan M Davis wrote:Well, foo() ~ bar() _is_ argument evaluation if you're dealing with an overloaded operator. And unfortunately, whether the spec is what the compiler does is frequently suspect anyway. So, who knows. - Jonathan M DavisOn Sunday, February 12, 2012 10:07:52 Ali Çehreli wrote:Actually, it *is* specified as left-to-right, except for assignments and argument evaluation. http://dlang.org/expression.html No idea if the compiler fully implements that part of the spec.Related question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++?It's currently unspecified. Walter has stated that he wants to make it so that it's always left to right, but I don't believe that he's done it yet, and it may or may not ever happen.
Feb 13 2012
On 02/13/12 20:47, Jonathan M Davis wrote:On Monday, February 13, 2012 19:47:03 Artur Skawina wrote:"argument evaluation" in this context means that given eg "f(a,b,c);" it's not specified in what order the expressions 'a', 'b', and 'c' are evaluated, which matters if they are dependent or have side effects. (depending on arg passing conventions it can make sense to implement this one way or the other). If an expression is specced as l-t-r (as CatExpression is here) then the call to foo() must happen before executing bar(); the operator only comes into play later. arturOn 02/13/12 18:57, Jonathan M Davis wrote:Well, foo() ~ bar() _is_ argument evaluation if you're dealing with an overloaded operator. And unfortunately, whether the spec is what the compiler does is frequently suspect anyway. So, who knows.On Sunday, February 12, 2012 10:07:52 Ali Çehreli wrote:Actually, it *is* specified as left-to-right, except for assignments and argument evaluation. http://dlang.org/expression.html No idea if the compiler fully implements that part of the spec.Related question: Does D define the order of evaluation in an expression like foo() ~ bar() Or is it unspecified as in C and C++?It's currently unspecified. Walter has stated that he wants to make it so that it's always left to right, but I don't believe that he's done it yet, and it may or may not ever happen.
Feb 13 2012
On Monday, February 13, 2012 21:49:05 Artur Skawina wrote:"argument evaluation" in this context means that given eg "f(a,b,c);" it's not specified in what order the expressions 'a', 'b', and 'c' are evaluated, which matters if they are dependent or have side effects. (depending on arg passing conventions it can make sense to implement this one way or the other). If an expression is specced as l-t-r (as CatExpression is here) then the call to foo() must happen before executing bar(); the operator only comes into play later.Ideally perhaps, but I expect that that's not true, because operator overloading is done via lowering. foo() ~ bar() would become opBinary!"~"(foo(), bar()); which is a normal function call. It's possible that the compiler always evaluates foo first, but I'd seriously advise against relying on it. In the long run, it probably will be guaranteed, because Walter wants to make it so that function arguments are always evaluated left-to-right, but until that happens, I wouldn't bet on foo() ~ bar() being guaranteed to have foo called before bar, even it's supposed to be. - Jonathan M Davis
Feb 13 2012
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.306.1329166430.20196.digitalmars-d-learn puremagic.com...Ideally perhaps, but I expect that that's not true, because operator overloading is done via lowering. foo() ~ bar() would become opBinary!"~"(foo(), bar());While your point is still correct, this will generally be lowered to foo().opBinary!"~"(bar()) or bar().opBinaryRight!"~"(foo()) Both of which do have a defined order of evaluation.
Feb 14 2012
On Wednesday, February 15, 2012 17:32:07 Daniel Murphy wrote:"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.306.1329166430.20196.digitalmars-d-learn puremagic.com...Ah, good point. - Jonathan M DavisIdeally perhaps, but I expect that that's not true, because operator overloading is done via lowering. foo() ~ bar() would become opBinary!"~"(foo(), bar());While your point is still correct, this will generally be lowered to foo().opBinary!"~"(bar()) or bar().opBinaryRight!"~"(foo()) Both of which do have a defined order of evaluation.
Feb 14 2012
On 02/13/12 21:52, Jonathan M Davis wrote:On Monday, February 13, 2012 21:49:05 Artur Skawina wrote:The important thing here is - the order absolutely *must* be foo(), then bar(), what happens under the hood is completely irrelevant. The reason is simple - if this is not what happens then it's a serious compiler bug. And if you can't rely on the order then it just shouldn't be documented. The order /could/ be undefined, so specifying it means the programmer has to assume he/she /can/ count that the compiler follows it - otherwise defining it wouldn't make any sense. IOW having the order defined, but not implemented, causes bugs that wouldn't be there without such definition; hence one has to assume that it *is* implemented (modulo unknown compiler bugs of course). Undefining the order is a much better solution than suggesting that users should assume the compiler is broken. It can always be re-defined later, switching from defined to undefined is not as easy. artur"argument evaluation" in this context means that given eg "f(a,b,c);" it's not specified in what order the expressions 'a', 'b', and 'c' are evaluated, which matters if they are dependent or have side effects. (depending on arg passing conventions it can make sense to implement this one way or the other). If an expression is specced as l-t-r (as CatExpression is here) then the call to foo() must happen before executing bar(); the operator only comes into play later.Ideally perhaps, but I expect that that's not true, because operator overloading is done via lowering. foo() ~ bar() would become opBinary!"~"(foo(), bar()); which is a normal function call. It's possible that the compiler always evaluates foo first, but I'd seriously advise against relying on it. In the long run, it probably will be guaranteed, because Walter wants to make it so that function arguments are always evaluated left-to-right, but until that happens, I wouldn't bet on foo() ~ bar() being guaranteed to have foo called before bar, even it's supposed to be.
Feb 13 2012
On Monday, February 13, 2012 22:24:38 Artur Skawina wrote:The important thing here is - the order absolutely *must* be foo(), then bar(), what happens under the hood is completely irrelevant. The reason is simple - if this is not what happens then it's a serious compiler bug. And if you can't rely on the order then it just shouldn't be documented. The order /could/ be undefined, so specifying it means the programmer has to assume he/she /can/ count that the compiler follows it - otherwise defining it wouldn't make any sense. IOW having the order defined, but not implemented, causes bugs that wouldn't be there without such definition; hence one has to assume that it *is* implemented (modulo unknown compiler bugs of course). Undefining the order is a much better solution than suggesting that users should assume the compiler is broken. It can always be re-defined later, switching from defined to undefined is not as easy.I'm not arguing that the order _shouldn't_ be defined and guaranteed. I'm just saying that I wouldn't trust the compiler to make such guarantees. If you find that bar gets evaluated before foo, then by all means, report it. But unless one of the dmd devs verifies in the code that it does indeed guarantee left-to- right evaluation of foo() ~ bar() even with operator overloading, I would consider it a bad idea to rely on it. Given that lowering is involved, I think that there's a high chance that the order is just as defined as directly calling op!"~"(foo(), bar()) would be. - Jonathan M Davis
Feb 13 2012
On 02/13/12 22:58, Jonathan M Davis wrote:On Monday, February 13, 2012 22:24:38 Artur Skawina wrote:I'm not arguing that it _should_ be defined - just pointing out that the fact that it currently _is_ means one should be able to assume it works. After all there's only one D frontend and it comes from the vendor that also effectively controls the language spec - so it's reasonable to expect things that are documented, but could have been omitted, to work. If the compiler does not currently implement these spec parts it would be much better to say that the order *will* be L-T-R, but right now is undefined. That way users won't be mislead and if somebody else decides do to a D compiler it will be clear what should happen. Switching later from L-T-R to Undefined breaks backwards compatibility, but doing it the other way is harmless. arturThe important thing here is - the order absolutely *must* be foo(), then bar(), what happens under the hood is completely irrelevant. The reason is simple - if this is not what happens then it's a serious compiler bug. And if you can't rely on the order then it just shouldn't be documented. The order /could/ be undefined, so specifying it means the programmer has to assume he/she /can/ count that the compiler follows it - otherwise defining it wouldn't make any sense. IOW having the order defined, but not implemented, causes bugs that wouldn't be there without such definition; hence one has to assume that it *is* implemented (modulo unknown compiler bugs of course). Undefining the order is a much better solution than suggesting that users should assume the compiler is broken. It can always be re-defined later, switching from defined to undefined is not as easy.I'm not arguing that the order _shouldn't_ be defined and guaranteed. I'm just
Feb 13 2012
On 02/13/2012 11:27 PM, Artur Skawina wrote:On 02/13/12 22:58, Jonathan M Davis wrote:D the language requires L-T-R for both binary operators and function invocation. If DMD the compiler does not implement this in all cases then that is a bug. Why should a compiler bug have any influence whatsoever on the *language specification* ? I cannot follow. Order of evaluation for assignment expressions seems to be undefined in DMD 2.057, the following code has differing behavior in presence or absence of the optimization flags: int foo(int x){writeln(x);return 0;} ref int bar(int a,int b,int c){return *(new int);} void main(){ bar(foo(0),foo(1),foo(2))=bar(foo(3),foo(4),foo(5)); } FWIW, I didn't find any other counter-examples.On Monday, February 13, 2012 22:24:38 Artur Skawina wrote:I'm not arguing that it _should_ be defined - just pointing out that the fact that it currently _is_ means one should be able to assume it works. After all there's only one D frontend and it comes from the vendor that also effectively controls the language spec - so it's reasonable to expect things that are documented, but could have been omitted, to work. If the compiler does not currently implement these spec parts it would be much better to say that the order *will* be L-T-R, but right now is undefined. That way users won't be mislead and if somebody else decides do to a D compiler it will be clear what should happen. Switching later from L-T-R to Undefined breaks backwards compatibility, but doing it the other way is harmless. arturThe important thing here is - the order absolutely *must* be foo(), then bar(), what happens under the hood is completely irrelevant. The reason is simple - if this is not what happens then it's a serious compiler bug. And if you can't rely on the order then it just shouldn't be documented. The order /could/ be undefined, so specifying it means the programmer has to assume he/she /can/ count that the compiler follows it - otherwise defining it wouldn't make any sense. IOW having the order defined, but not implemented, causes bugs that wouldn't be there without such definition; hence one has to assume that it *is* implemented (modulo unknown compiler bugs of course). Undefining the order is a much better solution than suggesting that users should assume the compiler is broken. It can always be re-defined later, switching from defined to undefined is not as easy.I'm not arguing that the order _shouldn't_ be defined and guaranteed. I'm just
Feb 13 2012
On 02/13/12 23:39, Timon Gehr wrote:On 02/13/2012 11:27 PM, Artur Skawina wrote:In theory it shouldn't, but it's much better to have a situation where the spec can be incrementally improved, than to end up having to make backwards incompatible changes later, when for example it's found that fixing some corner cases would be too hard. And I keep saying that *if* the order is defined then it should be followed, otherwise it would be better to document the actual behavior; that's all. Is L-T-R for function arg evaluation documented somewhere, btw? The "expression" dlang.org page has it as implementation-defined. arturOn 02/13/12 22:58, Jonathan M Davis wrote:D the language requires L-T-R for both binary operators and function invocation. If DMD the compiler does not implement this in all cases then that is a bug. Why should a compiler bug have any influence whatsoever on the *language specification* ? I cannot follow.On Monday, February 13, 2012 22:24:38 Artur Skawina wrote:I'm not arguing that it _should_ be defined - just pointing out that the fact that it currently _is_ means one should be able to assume it works. After all there's only one D frontend and it comes from the vendor that also effectively controls the language spec - so it's reasonable to expect things that are documented, but could have been omitted, to work. If the compiler does not currently implement these spec parts it would be much better to say that the order *will* be L-T-R, but right now is undefined. That way users won't be mislead and if somebody else decides do to a D compiler it will be clear what should happen. Switching later from L-T-R to Undefined breaks backwards compatibility, but doing it the other way is harmless. arturThe important thing here is - the order absolutely *must* be foo(), then bar(), what happens under the hood is completely irrelevant. The reason is simple - if this is not what happens then it's a serious compiler bug. And if you can't rely on the order then it just shouldn't be documented. The order /could/ be undefined, so specifying it means the programmer has to assume he/she /can/ count that the compiler follows it - otherwise defining it wouldn't make any sense. IOW having the order defined, but not implemented, causes bugs that wouldn't be there without such definition; hence one has to assume that it *is* implemented (modulo unknown compiler bugs of course). Undefining the order is a much better solution than suggesting that users should assume the compiler is broken. It can always be re-defined later, switching from defined to undefined is not as easy.I'm not arguing that the order _shouldn't_ be defined and guaranteed. I'm just
Feb 13 2012
mmmhhh.... this is interesting nevertheless i don't understand the solution of my problem, and i cannot even understand it's origin: void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); } why there is not way i cannot achive "arcd"?
Feb 14 2012
On 02/14/2012 12:59 PM, RenatoL wrote:mmmhhh.... this is interesting nevertheless i don't understand the solution of my problem, and i cannot even understand it's origin: void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); } why there is not way i cannot achive "arcd"?import std.stdio; import std.utf; void main() { string s1 = "abcd"; immutable firstCharStride = stride(s1, 0); immutable secondCharStride = stride(s1, firstCharStride); auto firstPart = s1[0..firstCharStride]; auto lastPart = s1[firstCharStride + secondCharStride..$]; s1 = firstPart ~ 'r' ~ lastPart; writeln(s1); } Ali
Feb 14 2012
On Tuesday, 14 February 2012 at 21:09:09 UTC, Ali Çehreli wrote:On 02/14/2012 12:59 PM, RenatoL wrote:I have come across similar problems using stride. Andrei Alexandrescu writes in his book on D that it is a subtle bug, if strings are not sliced using stride(s, index). However, if index is the length of another string there might be a mismatch, because stride() returns the "number of bytes in the UTF-8/16/32 sequence" which may not correspond to length/the index needed. E.g. if you have a string "chat" and you want to slice it as follows: auto word = "chat"; // Do some regex search ... // m[0] is the matched start sequence "ch" auto substring = word[m[0].length..$]; // "at" Using stride() returns 1 and not 2 (length of "ch"), so you'd get "hat" instead of "at". To avoid this and keep it "legal", is it possible to determine a string's length with std.utf.count() to determine the length of a string via utf code points (or toUCSindex())? auto substring = word[std.utf.count(m[0])..$]; // "at"mmmhhh.... this is interesting nevertheless i don't understand the solution of my problem, and i cannot even understand it's origin: void main() { string s1 = "abcd"; s1 = s1[stride(s1,0)..1] ~ 'r' ~ s1[2..$]; writeln(s1); } why there is not way i cannot achive "arcd"?import std.stdio; import std.utf; void main() { string s1 = "abcd"; immutable firstCharStride = stride(s1, 0); immutable secondCharStride = stride(s1, firstCharStride); auto firstPart = s1[0..firstCharStride]; auto lastPart = s1[firstCharStride + secondCharStride..$]; s1 = firstPart ~ 'r' ~ lastPart; writeln(s1); } Ali
Mar 14 2012
On Monday, February 13, 2012 23:27:37 Artur Skawina wrote:I'm not arguing that it _should_ be defined - just pointing out that the fact that it currently _is_ means one should be able to assume it works. After all there's only one D frontend and it comes from the vendor that also effectively controls the language spec - so it's reasonable to expect things that are documented, but could have been omitted, to work. If the compiler does not currently implement these spec parts it would be much better to say that the order *will* be L-T-R, but right now is undefined. That way users won't be mislead and if somebody else decides do to a D compiler it will be clear what should happen. Switching later from L-T-R to Undefined breaks backwards compatibility, but doing it the other way is harmless.The reality of the matter is that the spec is untrustworthy. The compiler may or may not follow it, and just because the spec says something and the compiler doesn't agree doesn't mean that the spec is going to win out. It's better than it used to be, and I think that Walter fixed a number of things in it recently, but the spec is notorious for being out-of-date when it comes to the little details. In this particular case, I'd fully expect that the spec is correct and that if the compiler doesn't follow suit, then it's buggy. However, it's also the kind of situation where I think that a bug would be very likely. So, I'd advise against relying on it, simply because the odds of your code being buggy (due to what is likely a compiler bug) are too high. - Jonathan M Davis
Feb 13 2012