Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On Sunday, February 24, 2013 04:39:55 Andrej Mitrovic wrote:
> It seems this doesn't work:
>
> import std.algorithm;
> auto b1 = qual(["foo"d], ["foo"]);
> auto b2 = equal(["foo"d.dup], ["foo"]);
>
> It's due to a constraint failure:
> is(typeof(r1.front == r2.front))
>
> The first call is:
> immutable(dchar)[]
> string
>
> The second:
> dchar[]
> string
>
> Anyway can we make `equal` work with these? It would be really useful if it worked.
Well, if r1.front and r2.front can't be compared, what do you expect? You're trying to compare an array of dstrings and an array of strings. strings and dstrings aren't comparable. What you need is some sort of recursive equals.
- Jonathan M Davis
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On 2/24/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> strings and dstrings aren't comparable.
Why aren't they? They're just different encodings of UTF, I'd expect Phobos to support comparing UTF8/UTF16/UTF32 against each other.
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On Sunday, February 24, 2013 05:18:18 Andrej Mitrovic wrote:
> On 2/24/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > strings and dstrings aren't comparable.
>
> Why aren't they? They're just different encodings of UTF, I'd expect Phobos to support comparing UTF8/UTF16/UTF32 against each other.
Because the compiler doesn't general deal on the level of code points. It deals with code units, and it doesn't generally treat strings as being special at all. So, you can't compare string and dstring any more than you can compare ubye[] and uint[]. Pretty much the only place in the language where you get automatic decoding is when you ask for it with a foreach loop by making the iteration type dchar. All the rest of it is Phobos, and equals is specifically the way to compare strings by code point. It just isn't recursive, which is why your'e having trouble.
However, now that I think about it, equal takes a predicate, so it would probably work to do something like
equal!"equal(a, b)"(["hello"d], ["hello"]);
- Jonathan M Davis
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On 2/24/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > Because the compiler doesn't general deal on the level of code points. It > deals with code units, and it doesn't generally treat strings as being > special > at all. So, you can't compare string and dstring any more than you can > compare > ubye[] and uint[]. Pretty much the only place in the language where you get > > automatic decoding is when you ask for it with a foreach loop by making the > > iteration type dchar. I'm specifically talking about Phobos, that's why I tried to use equals rather than == which doesn't work of course. > It just isn't recursive, which is why you're having trouble. I don't understand, what does recursion have to do with anything? I want these to work: "foo".equal("foo".dup); "foo".equal("foo"w); "foo".equal("foo"w.dup); "foo".equal("foo"d); "foo".equal("foo"d.dup); Or is there some other function that can be used to compare two strings whatever their encoding may be? |
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On Sunday, February 24, 2013 06:21:05 Andrej Mitrovic wrote: > On 2/24/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > > Because the compiler doesn't general deal on the level of code points. It > > deals with code units, and it doesn't generally treat strings as being > > special > > at all. So, you can't compare string and dstring any more than you can > > compare > > ubye[] and uint[]. Pretty much the only place in the language where you > > get > > > > automatic decoding is when you ask for it with a foreach loop by making the > > > > iteration type dchar. > > I'm specifically talking about Phobos, that's why I tried to use equals rather than == which doesn't work of course. > > > It just isn't recursive, which is why you're having trouble. > > I don't understand, what does recursion have to do with anything? > > I want these to work: > > "foo".equal("foo".dup); > "foo".equal("foo"w); > "foo".equal("foo"w.dup); > "foo".equal("foo"d); > "foo".equal("foo"d.dup); Those _do_ work. The problem is that you're not trying that; you're trying ["foo"].equal(["foo"d]); You're attempting to compare string[] and dstring[] with equal rather than string and dstring. > Or is there some other function that can be used to compare two strings whatever their encoding may be? The problem is that you're trying to compare string[] and dstring[]. They're not comparable with ==, so you tried equal, which means trying to compare string and dstring with ==, because that's what the types of front are on those ranges, and they aren't comparable with ==. What I mean by recursive is that you need to keep operating on each inner type with equal rather than ==. So, if you have string[][][][][] and dstring[][][] [][], the only way to do it would be if each level of comparison used equal rather than ==. And most everything in Phobos uses ==, not equal. equal is only used when you specifically ask for it, and it isn't recursive - it doesn't compare each of the layers with equal. It simply compares fronts with ==. However, if you're only dealing with comparing arrays of strings (e.g. string[] and dstring[]) rather than deeper levels (e.g. string[][][][] and dstring[][][][]), then giving equal a different predicate should work. So, you'd do something like assert(["foo"].equal!"equal(a, b)"(["foo"d])); - Jonathan M Davis |
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 24 February 2013 at 04:47:41 UTC, Jonathan M Davis wrote: > However, now that I think about it, equal takes a predicate, so it would > probably work to do something like > > equal!"equal(a, b)"(["hello"d], ["hello"]); > > - Jonathan M Davis Yes, and you don't even need to use a mixin. This is a known "issue", and is specifically covered and "pseudo-documented" the source unittests. Copy pasted straight from the source: //Should not compile, because "string == dstring" is illegal static assert(!is(typeof(equal(["hello", "world"], ["hello"d, "world"d])))); //However, arrays of non-matching string can be compared using equal!equal. Neat-o! equal!equal(["hello", "world"], ["hello"d, "world"d]); |
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Sunday, February 24, 2013 12:24:21 monarch_dodra wrote:
> On Sunday, 24 February 2013 at 04:47:41 UTC, Jonathan M Davis
>
> wrote:
> > However, now that I think about it, equal takes a predicate, so
> > it would
> > probably work to do something like
> >
> > equal!"equal(a, b)"(["hello"d], ["hello"]);
> >
> > - Jonathan M Davis
>
> Yes, and you don't even need to use a mixin.
>
> This is a known "issue", and is specifically covered and "pseudo-documented" the source unittests.
>
> Copy pasted straight from the source:
>
> //Should not compile, because "string == dstring" is illegal
> static assert(!is(typeof(equal(["hello", "world"], ["hello"d,
> "world"d]))));
> //However, arrays of non-matching string can be compared using
> equal!equal. Neat-o!
> equal!equal(["hello", "world"], ["hello"d, "world"d]);
Given that equal is a templated function, I'm surprised that it's possible to pass it without it being fully instantiated. Usually, templates have to be fully instantiated before you can alias them.
- Jonathan M Davis
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 24 February 2013 at 11:35:28 UTC, Jonathan M Davis wrote:
> On Sunday, February 24, 2013 12:24:21 monarch_dodra wrote:
>> On Sunday, 24 February 2013 at 04:47:41 UTC, Jonathan M Davis
>>
>> wrote:
>> > However, now that I think about it, equal takes a predicate, so
>> > it would
>> > probably work to do something like
>> >
>> > equal!"equal(a, b)"(["hello"d], ["hello"]);
>> >
>> > - Jonathan M Davis
>>
>> Yes, and you don't even need to use a mixin.
>>
>> This is a known "issue", and is specifically covered and
>> "pseudo-documented" the source unittests.
>>
>> Copy pasted straight from the source:
>>
>> //Should not compile, because "string == dstring" is illegal
>> static assert(!is(typeof(equal(["hello", "world"], ["hello"d,
>> "world"d]))));
>> //However, arrays of non-matching string can be compared using
>> equal!equal. Neat-o!
>> equal!equal(["hello", "world"], ["hello"d, "world"d]);
>
> Given that equal is a templated function, I'm surprised that it's possible to
> pass it without it being fully instantiated. Usually, templates have to be
> fully instantiated before you can alias them.
>
> - Jonathan M Davis
My first reaction when I stumbled upon it actually. Then again, can't the same be said about lambas? Technically, they *are* templates, since the type is determined when they are actually called.
Also, when you say "alias", do you mean "pass as alias parameter", or the actual "alias"? Because templates can be aliased un parametrized.
import std.algorithm, std.stdio;
void main()
{
alias map2 = map;
writeln(map2!"a * 2"([1, 2, 3]));
}
|
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
On 2/24/13, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > Those _do_ work. The problem is that you're not trying that; you're trying > ["foo"].equal(["foo"d]); Ah that makes sense, thanks. A run of the mill implementation takes care of things: bool equal(Range1, Range2)(Range1 r1, Range2 r2) if (isInputRange!Range1 && isInputRange!Range2 && isInputRange!(ElementType!Range1) && isInputRange!(ElementType!Range2)) { if (r1.length != r2.length) return false; foreach (lhs, rhs; zip(r1, r2)) { if (!.equal(lhs, rhs)) return false; } return true; } It's not tested though, but I see what you mean by recursion now. I'll file an enhancement. One thing I don't understand is why the above won't work if I put it in my own module (compile-time error), it has to be put in std.algorithm for all the template overloads to be part of one overload set. Using aliases won't work either, e.g.: import std.algorithm; alias std.algorithm.equal equal; // conflict bool equal(Range1, Range2)(Range1 r1, Range2 r2) if (isInputRange!Range1 && isInputRange!Range2 && isInputRange!(ElementType!Range1) && isInputRange!(ElementType!Range2)) { if (r1.length != r2.length) return false; foreach (lhs, rhs; zip(r1, r2)) { if (!.equal(lhs, rhs)) return false; } return true; } It sounds to me like it's a compiler bug. |
February 24, 2013 Re: Error using `equal` with various string types | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Sunday, February 24, 2013 13:02:46 monarch_dodra wrote: > My first reaction when I stumbled upon it actually. Then again, can't the same be said about lambas? Technically, they *are* templates, since the type is determined when they are actually called. > > Also, when you say "alias", do you mean "pass as alias parameter", or the actual "alias"? Both. > Because templates can be > aliased un parametrized. > > import std.algorithm, std.stdio; > > void main() > { > alias map2 = map; > writeln(map2!"a * 2"([1, 2, 3])); > } Maybe the problem is when you try and partially instantiate them, but that's why some templated functions (like map) are a template wrapping a templated function rather than just being a straight templated function. - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation