www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - nextPermutation: why possible for dchar but not for char?

reply "Ivan Kazmenko" <gassa mail.ru> writes:
Another quick question, two of them.

1. This is a minimal example of trying the permutations of a 
character array.

-----
import std.algorithm;
void main () {
     char [] a;
     do { } while (nextPermutation(a));
}
-----

This gives a compile error.  However, it works when I change 
"char [] a" to "dchar [] a".  Why?

I understand that permuting a char [] array might be wrong way to 
go when dealing with Unicode.  But what if, at this point of the 
program, I am sure I'm dealing with ASCII and just want 
efficiency?  Should I convert to ubyte [] somehow - what's the 
expected way then?  The "cast (ubyte [])" works, but "to!(ubyte 
[])" fails at runtime, expecting a string representation of the 
array, not its raw contents.

2. Why does nextPermutation hang up for empty arrays?  I suppose 
that's a bug?

Ivan Kazmenko.
Dec 28 2013
next sibling parent reply "Ivan Kazmenko" <gassa mail.ru> writes:
On Saturday, 28 December 2013 at 22:55:39 UTC, Ivan Kazmenko 
wrote:
 Another quick question, two of them.

 1. This is a minimal example of trying the permutations of a 
 character array.

 -----
 import std.algorithm;
 void main () {
     char [] a;
     do { } while (nextPermutation(a));
 }
 -----

 This gives a compile error.  However, it works when I change 
 "char [] a" to "dchar [] a".  Why?

 I understand that permuting a char [] array might be wrong way 
 to go when dealing with Unicode.  But what if, at this point of 
 the program, I am sure I'm dealing with ASCII and just want 
 efficiency?  Should I convert to ubyte [] somehow - what's the 
 expected way then?  The "cast (ubyte [])" works, but "to!(ubyte 
 [])" fails at runtime, expecting a string representation of the 
 array, not its raw contents.

 2. Why does nextPermutation hang up for empty arrays?  I 
 suppose that's a bug?

 Ivan Kazmenko.
Also, the example at http://dlang.org/phobos/std_algorithm.html#nextPermutation is wrong: while (nextPermutation(a)) { } should in fact be do { } while (nextPermutation(a)); as above, or we miss the very first permutation.
Dec 28 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 28 December 2013 at 22:58:43 UTC, Ivan Kazmenko 
wrote:
 Also, the example at
 http://dlang.org/phobos/std_algorithm.html#nextPermutation
 is wrong:
 while (nextPermutation(a)) { }
 should in fact be
 do { } while (nextPermutation(a));
 as above, or we miss the very first permutation.
Noted. I'll try to fix that in the comming days. Or if anybody else submits the pull, I'll merge it (*hint* *hint*, *wink*)
Dec 28 2013
parent "Ivan Kazmenko" <gassa mail.ru> writes:
On Saturday, 28 December 2013 at 23:07:21 UTC, monarch_dodra 
wrote:
 Also, the example at
 http://dlang.org/phobos/std_algorithm.html#nextPermutation
 is wrong:
 while (nextPermutation(a)) { }
 should in fact be
 do { } while (nextPermutation(a));
 as above, or we miss the very first permutation.
Noted. I'll try to fix that in the comming days. Or if anybody else submits the pull, I'll merge it (*hint* *hint*, *wink*)
Here it is: https://github.com/D-Programming-Language/phobos/pull/1822 Or should it have been done in a separate branch?.. The bugtracker (http://d.puremagic.com/issues/) seems to be down at the moment, so there's no issue associated with it. Ivan Kazmenko.
Dec 29 2013
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 28 December 2013 at 22:55:39 UTC, Ivan Kazmenko 
wrote:
 Another quick question, two of them.

 1. This is a minimal example of trying the permutations of a 
 character array.

 -----
 import std.algorithm;
 void main () {
     char [] a;
     do { } while (nextPermutation(a));
 }
 -----

 This gives a compile error.  However, it works when I change 
 "char [] a" to "dchar [] a".  Why?

 I understand that permuting a char [] array might be wrong way 
 to go when dealing with Unicode.  But what if, at this point of 
 the program, I am sure I'm dealing with ASCII and just want 
 efficiency?  Should I convert to ubyte [] somehow - what's the 
 expected way then?
Because next permutation (AFAIK) works on ranges with *assignable* elements, and "char[]" is not such a range: It is a read-only range of dchars. Arguably, the implementation *could* work for it, *even* while taking into consideration unicode (using the underlying UTF8 knowledge). You should file an ER for that. But currently, this is not the case, so you have to look for a workaround.
 The "cast (ubyte [])" works, but "to!(ubyte [])" fails at 
 runtime, expecting a string representation of the array, not 
 its raw contents.
You can use "representation" to "conveniently" transform a string/wstring/dstring to its corresponding numeric type (ubyte/ushort/uint). That *should* work. "Unfortunatly", "to!T(string)" often does a parse. As convenient as it is, I think the added ambiguity makes it often wrong.
 2. Why does nextPermutation hang up for empty arrays?  I 
 suppose that's a bug?
I suppose so. Please file it. If it is deemed "illegal", at the very least, it should throw.
 Ivan Kazmenko.
Dec 28 2013
next sibling parent reply "Ivan Kazmenko" <gassa mail.ru> writes:
On Saturday, 28 December 2013 at 23:05:54 UTC, monarch_dodra 
wrote:
 1. This is a minimal example of trying the permutations of a 
 character array.

 -----
 import std.algorithm;
 void main () {
    char [] a;
    do { } while (nextPermutation(a));
 }
 -----

 This gives a compile error.  However, it works when I change 
 "char [] a" to "dchar [] a".  Why?
Because next permutation (AFAIK) works on ranges with *assignable* elements, and "char[]" is not such a range: It is a read-only range of dchars.
Ouch, is it an exception hard-coded into the language itself? I thought it's just the nextPermutation's parameter type restrictions which don't allow "char []"...
 2. Why does nextPermutation hang up for empty arrays?  I 
 suppose that's a bug?
I suppose so. Please file it. If it is deemed "illegal", at the very least, it should throw.
OK, will do that tomorrow (on Sunday).
 Also, the example at
 http://dlang.org/phobos/std_algorithm.html#nextPermutation
 is wrong:
 while (nextPermutation(a)) { }
 should in fact be
 do { } while (nextPermutation(a));
 as above, or we miss the very first permutation.
Noted. I'll try to fix that in the comming days. Or if anybody else submits the pull, I'll merge it (*hint* *hint*, *wink*)
Hmm, I'll look into how hard is that for a start... Ivan Kazmenko.
Dec 28 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 28 December 2013 at 23:38:38 UTC, Ivan Kazmenko 
wrote:
 Ouch, is it an exception hard-coded into the language itself?  
 I thought it's just the nextPermutation's parameter type 
 restrictions which don't allow "char []"...
No, a "char[]" is just a "char[]" as far as the language is concerned[1]. However, for the *phobos* range abstraction, (the front/popFront/empty) primitives, a char[] is a range of dchars. Once you've defined char[] as such a range, it affects all of phobos. It's critiqued every now and then, but overall, it has proven to increase code correctness, at the cost (sometimes) of rejecting code that might be incorrect. Long story short: If you want to handle UTF, you have to handle it *explicitly*. *I* think it is a good compromise. [1] the *only* place (AFAIK) that dmd looks at a string as a range of dchars is in a "foreach(dchar c; s)" loop. But even then, if you don't specify "dchar", then c will default to char.
Dec 29 2013
prev sibling parent "Ivan Kazmenko" <gassa mail.ru> writes:
 2. Why does nextPermutation hang up for empty arrays?  I 
 suppose that's a bug?
I suppose so. Please file it. If it is deemed "illegal", at the very least, it should throw.
My fault, i mis-used it. The right behavior for ranges of size 0 and 1 is checked explicitly in the unittests. Ivan Kazmenko.
Dec 29 2013