Why foreach(c; someString) must yield dchar
Rainer Deyke
rainerd at eldwood.com
Wed Aug 18 20:11:26 PDT 2010
On 8/18/2010 20:37, dsimcha wrote:
> I've been hacking in Phobos and parallelfuture and I've come to the conclusion
> that having typeof(c) in the expression foreach(c; string.init) not be a dchar
> is simply ridiculous.
I have long ago come to the opposite conclusion. An array of 'char'
should act like any other array. If you want a sequence of 'dchar' that
is internally stored as an array of 'char', don't call it 'char[]'.
You propose to fix a special case by adding more special cases. This
will increase, not decrease, the number of cases that will need special
treatment in generic code.
Iterating over a sequence of 'char' as a sequence of 'dchar' is very
useful. Implementing this functionality as a language feature, tied to
the built-in array type, is just plain wrong.
> static assert(is(typeof({
> foreach(elem; T.init) {
> return elem;
> }
> assert(0);
> }) == ElementType!(T));
>
> Looks reasonable. FAILS on narrow strings.
Because ElementType!(string) is broken.
> size_t walkLength1(R)(R input) {
> size_t ret = 0;
> foreach(elem; input) {
> ret++;
> }
>
> return ret;
> }
>
> size_t walkLength2(R)(R input) {
> size_t ret = 0;
> while(!input.empty) {
> ret++;
> input.popFront();
> }
>
> return ret;
> }
>
> assert(walkLength1(stuff) == walkLength2(stuff));
>
> FAILS if stuff is a narrow string with characters that aren't a single code point.
Because 'popFront' is broken for narrow strings.
> void printRange(R)(R range) {
> foreach(elem; range) {
> write(elem, ' ');
> }
> writeln();
> }
>
> Prints garbage if range is a string with characters that aren't a single code
> point.
Prints bytes from the string separated by spaces. This may be
intentional behavior if the parser on the other side is not utf-aware.
--
Rainer Deyke - rainerd at eldwood.com
More information about the Digitalmars-d
mailing list