Thread overview
importing std.algorithm breaks std.string.count
Sep 17, 2010
Seth Hoenig
Sep 17, 2010
Seth Hoenig
Sep 23, 2010
Daniel Murphy
September 17, 2010
I have these two minimal programs:


import std.string;
void main()
{
    string str = "abc";
    int i = str.count("ab");

}



and:



import std.string;
import std.algorithm;
void main()
{
    string str = "abc";
    int i = str.count("ab");

}



The only difference is line 2, where I import std.algorithm.
The first program compiles fine, but the second program does not compile,
spitting out the error message:

bash-3.2$ dmd -ofdummy dummy.d
/u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(176): Error:
static assert  "Bad binary function q{a == b}. You need to use a valid D
expression using symbols a of type dchar and b of type string."
/u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(179):
instantiated from here: Body!(dchar,string)
/u/sah2659/dmd2/linux/bin/../../src/phobos/std/algorithm.d(3410):
instantiated from here: result!(dchar,string)
dummy.d(7):        instantiated from here: count!("a == b",string,string)


I can't imagine I'm the first person to notice a bug like this, so is there something I am doing wrong?


September 17, 2010
On Fri, 17 Sep 2010 17:15:31 -0400, Seth Hoenig <seth.a.hoenig@gmail.com> wrote:

> I have these two minimal programs:
>
>
> import std.string;
> void main()
> {
>     string str = "abc";
>     int i = str.count("ab");
>
> }
>
>
>
> and:
>
>
>
> import std.string;
> import std.algorithm;
> void main()
> {
>     string str = "abc";
>     int i = str.count("ab");
>
> }
>
>
>
> The only difference is line 2, where I import std.algorithm.
> The first program compiles fine, but the second program does not compile,
> spitting out the error message:
>
> bash-3.2$ dmd -ofdummy dummy.d
> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(176): Error:
> static assert  "Bad binary function q{a == b}. You need to use a valid D
> expression using symbols a of type dchar and b of type string."
> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(179):
> instantiated from here: Body!(dchar,string)
> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/algorithm.d(3410):
> instantiated from here: result!(dchar,string)
> dummy.d(7):        instantiated from here: count!("a == b",string,string)
>
>
> I can't imagine I'm the first person to notice a bug like this, so is there
> something I am doing wrong?

I see two bugs here.  First, this should be an ambiguity error, because count matches both std.algorithm.count and std.string.count.  The compiler should refuse to compile this I think.

Second, std.algorithm.count looks like this:

size_t count(alias pred = "a == b", Range, E)(Range r, E value) if (isInputRange!(Range))

So, E can be any type, completely unrelated to strings, I could do:

count!(string, int[]) which makes no sense.

I think the sig should be

size_t count(alias pred = "a == b", Range, E)(Range r, E value) if (isInputRange!(Range) && isImplicitlyConvertable!(E, ElementType!(Range)))

-Steve
September 17, 2010
Submitted *Issue 4883 <http://d.puremagic.com/issues/show_bug.cgi?id=4883>


*
On Fri, Sep 17, 2010 at 4:30 PM, Steven Schveighoffer
<schveiguy@yahoo.com>wrote:

> On Fri, 17 Sep 2010 17:15:31 -0400, Seth Hoenig <seth.a.hoenig@gmail.com> wrote:
>
>  I have these two minimal programs:
>>
>>
>> import std.string;
>> void main()
>> {
>>    string str = "abc";
>>    int i = str.count("ab");
>>
>> }
>>
>>
>>
>> and:
>>
>>
>>
>> import std.string;
>> import std.algorithm;
>> void main()
>> {
>>    string str = "abc";
>>    int i = str.count("ab");
>>
>> }
>>
>>
>>
>> The only difference is line 2, where I import std.algorithm.
>> The first program compiles fine, but the second program does not compile,
>> spitting out the error message:
>>
>> bash-3.2$ dmd -ofdummy dummy.d
>> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(176): Error:
>> static assert  "Bad binary function q{a == b}. You need to use a valid D
>> expression using symbols a of type dchar and b of type string."
>> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/functional.d(179):
>> instantiated from here: Body!(dchar,string)
>> /u/sah2659/dmd2/linux/bin/../../src/phobos/std/algorithm.d(3410):
>> instantiated from here: result!(dchar,string)
>> dummy.d(7):        instantiated from here: count!("a == b",string,string)
>>
>>
>> I can't imagine I'm the first person to notice a bug like this, so is
>> there
>> something I am doing wrong?
>>
>
> I see two bugs here.  First, this should be an ambiguity error, because count matches both std.algorithm.count and std.string.count.  The compiler should refuse to compile this I think.
>
> Second, std.algorithm.count looks like this:
>
> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if
> (isInputRange!(Range))
>
> So, E can be any type, completely unrelated to strings, I could do:
>
> count!(string, int[]) which makes no sense.
>
> I think the sig should be
>
> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if
> (isInputRange!(Range) && isImplicitlyConvertable!(E, ElementType!(Range)))
>
> -Steve
>


September 23, 2010
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:op.vi64pdhveav7ka@localhost.localdomain...
> Second, std.algorithm.count looks like this:
>
> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if (isInputRange!(Range))
>
> So, E can be any type, completely unrelated to strings, I could do:
>
> count!(string, int[]) which makes no sense.
>
> I think the sig should be
>
> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if (isInputRange!(Range) && isImplicitlyConvertable!(E, ElementType!(Range)))
>
> -Steve

Except you can call it like this:

string s = "1234";
int[] a = [1, 2, 3];
count!"cast(int)(a - '0') == b.length"(s, a);

Which is perfectly valid.


September 23, 2010
On Thu, 23 Sep 2010 02:19:55 -0400, Daniel Murphy <yebblies@nospamgmail.com> wrote:

> "Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message
> news:op.vi64pdhveav7ka@localhost.localdomain...
>> Second, std.algorithm.count looks like this:
>>
>> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if
>> (isInputRange!(Range))
>>
>> So, E can be any type, completely unrelated to strings, I could do:
>>
>> count!(string, int[]) which makes no sense.
>>
>> I think the sig should be
>>
>> size_t count(alias pred = "a == b", Range, E)(Range r, E value) if
>> (isInputRange!(Range) && isImplicitlyConvertable!(E, ElementType!(Range)))
>>
>> -Steve
>
> Except you can call it like this:
>
> string s = "1234";
> int[] a = [1, 2, 3];
> count!"cast(int)(a - '0') == b.length"(s, a);
>
> Which is perfectly valid.

and insane :)

count(s, cast(char)(a.length + '0'));

-Steve