std.algorithm.remove and principle of least astonishment

Steven Schveighoffer schveiguy at yahoo.com
Sat Oct 16 11:39:38 PDT 2010


On Sat, 16 Oct 2010 14:29:59 -0400, klickverbot <see at klickverbot.at> wrote:

> Hello all,
>
> I decided to have a go at solving some easy programming puzzles with  
> D2/Phobos to see how Phobos, especially ranges and std.algorithm, work  
> out in simple real-world use cases (the puzzle in question is from  
> hacker.org, by the way).
>
> The following code is a direct translation of a simple problem  
> description to D (it is horrible from performance point of view, but  
> that's certainly no issue here).
>
> ---
> import std.algorithm;
> import std.conv;
> import std.stdio;
>
> // The original input string is longer, but irrelevant to this post.
> enum INPUT = "93752xxx746x27x1754xx90x93xxxxx238x44x75xx087509";
>
> void main() {
>     uint sum;
>
>     auto tmp = INPUT.dup;
>     size_t i;
>     while ( i < tmp.length ) {
>        char c = tmp[ i ];
>        if ( c == 'x' ) {
>           tmp = remove( tmp, i );
>           i -= 2;
>        } else {
>           sum += to!uint( [ c ] );
>           ++i;
>        }
>     }
>
>     writeln( sum );
> }
> ---
>
> Quite contrary to what you would expect, the call to »remove« fails to  
> compile with the following error messages: »std/algorithm.d(4287):  
> Error: front(src) is not an lvalue« and »std/algorithm.d(4287): Error:  
> front(tgt) is not an lvalue«.

My guess is that since INPUT is a string, phobos has unwisely decided to  
treat strings not as random access arrays of chars, but as a bidirectional  
range of dchar.  This means that even though you can randomly access the  
characters (phobos can't take that away from you), it artificially imposes  
restrictions (such as making front an rvalue) where it wouldn't do the  
same to an int[] or ubyte[].

Andrei, I am increasingly seeing people struggling with the decision to  
make strings bidirectional ranges of dchar instead of what the compiler  
says they are.  This needs a different solution.  It's too  
confusing/difficult to deal with.

I suggest wrapping a char[] or wchar[] (of all constancies) with a special  
range that imposes the restrictions.  This means people will have to use  
these ranges when they want to treat them as bidir ranges of dchar, but  
the current situation is at least annoying, if not a complete turn-off to  
D.  And it vastly simplifies code that uses ranges, since they now don't  
have to contain special cases for char[] and wchar[].

-Steve


More information about the Digitalmars-d mailing list