View mode: basic / threaded / horizontal-split · Log in · Help
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?
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?
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?
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?
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?
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?
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?
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?
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?
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
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home