July 09, 2012 Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Almost every time I'm trying to use std.algorithm I run into some kind of error, for what seems to be fairly trivial and what one would expect to work. It feels like I'm constantly fighting with std.algorithm. For example: import std.algorithm; import std.range; struct Foo {} auto f = Foo(); auto foos = [f]; auto foo = foos.map!(x => "foo"); auto bar = foo.chain("bar"); This simple example result in the follow error: http://pastebin.com/E4LV2UBE Another example: auto str = ["foo", "bar"].map!(x => x); auto f = str.sort(); Results in: http://pastebin.com/BeePWQk9 I'm using DMD 2.059. -- /Jacob Carlborg |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 7/9/12 4:09 PM, Jacob Carlborg wrote: > Almost every time I'm trying to use std.algorithm I run into some kind > of error, for what seems to be fairly trivial and what one would expect > to work. It feels like I'm constantly fighting with std.algorithm. For > example: > > import std.algorithm; > import std.range; > > struct Foo {} > > auto f = Foo(); > auto foos = [f]; > auto foo = foos.map!(x => "foo"); > auto bar = foo.chain("bar"); > > This simple example result in the follow error: > > http://pastebin.com/E4LV2UBE So foo is a range of strings, because each element of it is a string. Then you want to chain a range of strings with a string, which is a range of dchar. That doesn't work, and I agree the error message should be more informative. To fix the example, write auto bar = foo.chain(["bar"]); > Another example: > > auto str = ["foo", "bar"].map!(x => x); > auto f = str.sort(); > > Results in: > > http://pastebin.com/BeePWQk9 The first error message is at clear as it goes: Error: r[i2] is not an lvalue Andrei |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Monday, July 09, 2012 22:09:54 Jacob Carlborg wrote: > Almost every time I'm trying to use std.algorithm I run into some kind of error, for what seems to be fairly trivial and what one would expect to work. It feels like I'm constantly fighting with std.algorithm. For example: > > import std.algorithm; > import std.range; > > struct Foo {} > > auto f = Foo(); > auto foos = [f]; > auto foo = foos.map!(x => "foo"); > auto bar = foo.chain("bar"); > > This simple example result in the follow error: > > http://pastebin.com/E4LV2UBE > > Another example: > > auto str = ["foo", "bar"].map!(x => x); > auto f = str.sort(); > > Results in: > > http://pastebin.com/BeePWQk9 > > I'm using DMD 2.059. >From the looks of it (without digging into what's really going on), in both cases, the problem seems to be that a template constraint is insufficiently precise, and so it's attempting to instantiate a template when that instantiation should fail. If a template constraint is written correctly, it should be impossible for the template constraint to succeed and the template instantiation fail. In general, I think that std.range and std.algorithm need better unit tests (ideally with every combination of range types that a particular function is supposed to work with being tested for that function). There are definitely cases where certain range types are supposed to work and don't (reference type ranges being a prime example). I've started on that but haven't gotten all that far yet. But with better testing, it should be much harder for a bad template constraint to be missed. - Jonathan M Davis |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 07/09/2012 01:16 PM, Andrei Alexandrescu wrote: > On 7/9/12 4:09 PM, Jacob Carlborg wrote: >> auto str = ["foo", "bar"].map!(x => x); >> auto f = str.sort(); >> >> Results in: >> >> http://pastebin.com/BeePWQk9 > > The first error message is at clear as it goes: > > Error: r[i2] is not an lvalue And a quick fix is to make an array first: auto str = ["foo", "bar"].map!(x => x)().array(); Also note the added () for map, which is needed when compiled with -property. Ali |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | Jacob Carlborg: > import std.algorithm; > import std.range; > > struct Foo {} > > auto f = Foo(); > auto foos = [f]; > auto foo = foos.map!(x => "foo"); > auto bar = foo.chain("bar"); I suggest to always compile with "-wi -property". chain() takes two iterables. This means both arguments need to yield the same type. But in your code foo is an iterable of strings, and you try to chain it an iterable of chars. In Python that works just because there are no chars, only single-char strings. It works if you turn the second argument of chain in an iterable of strings: import std.stdio, std.algorithm, std.range; void main() { import std.algorithm; import std.range; struct Foo {} auto f = Foo(); auto foos = [f]; auto foo = foos.map!(x => "foo")(); auto bar = foo.chain(["bar"]); writeln(bar); } > This simple example result in the follow error: > > http://pastebin.com/E4LV2UBE > > Another example: > > auto str = ["foo", "bar"].map!(x => x); > auto f = str.sort(); Map returns a lazy iterable. Generally you need an eager random-access iterable to sort (but it seems there are some exceptions like when you sort a zip...). Bye, bearophile |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 07/09/2012 10:23 PM, Ali Çehreli wrote:
> On 07/09/2012 01:16 PM, Andrei Alexandrescu wrote:
> > On 7/9/12 4:09 PM, Jacob Carlborg wrote:
>
> >> auto str = ["foo", "bar"].map!(x => x);
> >> auto f = str.sort();
> >>
> >> Results in:
> >>
> >> http://pastebin.com/BeePWQk9
> >
> > The first error message is at clear as it goes:
> >
> > Error: r[i2] is not an lvalue
>
> And a quick fix is to make an array first:
>
> auto str = ["foo", "bar"].map!(x => x)().array();
>
> Also note the added () for map, which is needed when compiled with
> -property.
>
> Ali
>
-property should be killed.
I mean, we can have either
map!(x => x)().array()
or
map!(x => x).array
It's blatantly obvious which one we want, especially when there are
more than two chained/nested calls. -property is good only for bracket
spam.
We need to implement @property properly, that is, @property function
pairs behave like fields and other functions can be called with the
parentheses left off. IIRC that is how it was designed initially.
|
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 07/09/2012 10:46 PM, bearophile wrote: > Jacob Carlborg: > >> import std.algorithm; >> import std.range; >> >> struct Foo {} >> >> auto f = Foo(); >> auto foos = [f]; >> auto foo = foos.map!(x => "foo"); >> auto bar = foo.chain("bar"); > > I suggest to always compile with "-wi -property". > Both -property and -w/-wi are broken and their only merit so far is to break my builds for no reason. -wi spits out about 4000 lines of false (duplicate) warnings when run against my code base. >> This simple example result in the follow error: >> >> http://pastebin.com/E4LV2UBE >> >> Another example: >> >> auto str = ["foo", "bar"].map!(x => x); >> auto f = str.sort(); > > Map returns a lazy iterable. Generally you need an eager > random-access iterable to sort (but it seems there are some > exceptions like when you sort a zip...). > Actually you need a random-access range with assignable elements. Map would need to be provided with an inverse mapping to support that. zip has assignable elements when the source ranges do. |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Monday, 9 July 2012 at 21:00:40 UTC, Timon Gehr wrote: > On 07/09/2012 10:46 PM, bearophile wrote: >> Jacob Carlborg: >> >>> import std.algorithm; >>> import std.range; >>> >>> struct Foo {} >>> >>> auto f = Foo(); >>> auto foos = [f]; >>> auto foo = foos.map!(x => "foo"); >>> auto bar = foo.chain("bar"); >> >> I suggest to always compile with "-wi -property". >> > > Both -property and -w/-wi are broken and their only merit so far is to break my builds for no reason. So far I have not seen one case where -property gives a wrong message. Please show me one. It's stuff for bugzilla. > -wi spits out about 4000 lines of false (duplicate) warnings when run against my code base. Please reduce those, maybe there is some false warning that I have not yet put in Bugzilla. In general -wi spits good warnings, with few exceptions. > zip has assignable elements when the source ranges do. It's shown in the Phobos docs too, but it's a little unexpected. See also: http://d.puremagic.com/issues/show_bug.cgi?id=8341 Bye, bearophile |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote: >> auto str = ["foo", "bar"].map!(x => x); >> auto f = str.sort(); [...] > The first error message is at clear as it goes: > Error: r[i2] is not an lvalue ... and I panic on reading your answer, because I do not find a `r' nor an `i2' in the source. Therefore "is not an lvalue" stays without sense. Some time ago Walter expressed, that he does not want D to become a language, which only specialists can interpret. But if error messages are part of a language and your "clear"-voting will stay, then "Hades" might become D's middle name. -manfred |
July 09, 2012 Re: Why is std.algorithm so complicated to use? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Monday, July 09, 2012 23:00:39 Timon Gehr wrote:
> On 07/09/2012 10:46 PM, bearophile wrote:
> > Jacob Carlborg:
> >> import std.algorithm;
> >> import std.range;
> >>
> >> struct Foo {}
> >>
> >> auto f = Foo();
> >> auto foos = [f];
> >> auto foo = foos.map!(x => "foo");
> >> auto bar = foo.chain("bar");
> >
> > I suggest to always compile with "-wi -property".
>
> Both -property and -w/-wi are broken and their only merit so far is to break my builds for no reason.
>
> -wi spits out about 4000 lines of false (duplicate) warnings when run
> against my code base.
I'd actually argue the opposite. I think that they should be the normal behavior, and if you're getting a ton of warnings, I'd argue that you have a ton of problems that need fixing. dmd is generally good about not having useless warnings. Now, with the current version of github, it unfortunately seems to spit out a bunch of duplicate messages for the same error/warning with templates in a number of cases, and _that_ should be fixed, but the warnings themselves are generally solid and indicators of a real problem.
And as I've expressed in the past, I think that -property is very much doing the right thing and that not strictly enforcing properties is horrible, but obivously we're in disagreement on that.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation