July 09, 2012
On 07/10/2012 12:53 AM, Jonathan M Davis wrote:
> 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.

Nonsense. I explicitly expressed that the warnings I get are bare of
value.

> dmd is generally good about not having
> useless warnings.

case 0,1: // warning: switch fallthrough (nonsense)
case 2,3:

This is the only kind of warning I get (clearly a bug, and it is reported). After that, the compiler spits out ~4000 lines of completely
unrelated internal AST from a different module.

> 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,

Language design shouldn't be based on statements like "I think it is
horrible". There is nothing objective in it.

> but obivously we're in disagreement on that.
>

What we disagree on is what is called a property and what is called a
function call. I am ok with disallowing function calls of the form
function = argument.
July 09, 2012
On Tuesday, July 10, 2012 01:20:21 Timon Gehr wrote:
> > 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,
> Language design shouldn't be based on statements like "I think it is horrible". There is nothing objective in it.

Without -property, it's lax. The rules aren't enforced. It allows you to use a function as if it were a property when it's not. Language rules should be strictly enforced not be left up to the programmer whether they want to bother following them or not. That just leads to confusion and bugs. If the API states that it's @property, so it should be used as a property. If the API says that it should be used as a function, then it should be used as a function. You wouldn't use () on a variable would you (aside from defining opCall)? I should think not, and I don't think that () should be left out on a function any more than they should be used on a variable. It's sloppy and confusing.

Regardless, TDPL calls for strict property enforcement, so that's where we're headed.

- Jonathan M Davis
July 09, 2012
On 07/09/2012 04:20 PM, Timon Gehr wrote:
> On 07/10/2012 12:53 AM, Jonathan M Davis wrote:

>> dmd is generally good about not having
>> useless warnings.
>
> case 0,1: // warning: switch fallthrough (nonsense)
> case 2,3:
>
> This is the only kind of warning I get (clearly a bug, and it is
> reported).

I thought the code above was illegal at least in 2.059. I get an error unless I use goto case:

void main()
{
    int i;
    int j;

    switch (i) {
    case 0,1:
        goto case;  // goto, embraced by D :)

    case 2,3:
        j = 42;
        break;

    default:
        j = 43;
    }
}

Ali

July 09, 2012
On 07/10/2012 01:41 AM, Ali Çehreli wrote:
> On 07/09/2012 04:20 PM, Timon Gehr wrote:
>  > On 07/10/2012 12:53 AM, Jonathan M Davis wrote:
>
>  >> dmd is generally good about not having
>  >> useless warnings.
>  >
>  > case 0,1: // warning: switch fallthrough (nonsense)
>  > case 2,3:
>  >
>  > This is the only kind of warning I get (clearly a bug, and it is
>  > reported).
>
> I thought the code above was illegal at least in 2.059.

You can write the code as
case 0: case 1: case 2,3:

and be ok.

> I get an error
> unless I use goto case:
>
> void main()
> {
>      int i;
>      int j;
>
>      switch (i) {
>      case 0,1:
>          goto case;  // goto, embraced by D :)
>
>      case 2,3:
>          j = 42;
>          break;
>
>      default:
>          j = 43;
>      }
> }
>
> Ali
>

The error only shows up if -w is used.
July 10, 2012
On 07/10/2012 01:34 AM, Jonathan M Davis wrote:
> On Tuesday, July 10, 2012 01:20:21 Timon Gehr wrote:
>>> 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,
>> Language design shouldn't be based on statements like "I think it is
>> horrible". There is nothing objective in it.
>
> Without -property, it's lax. The rules aren't enforced.

Yes they are. It is just another set of rules.

> It allows you to use a function as if it were a property when it's not.

No, it allows you to call a function by calling it's name. Walter
presumably got this from Eiffel, where it is called 'uniform access
principle'.

> Language rules should be
> strictly enforced not be left up to the programmer whether they want to bother
> following them or not.  That just leads to confusion and bugs.

That is the realm of unsafe casts. We are just discussing syntax here.
Less brackets are better, because it is easier to match them. Fact.

> If the API
> states that it's @property, so it should be used as a property. If the API
> says that it should be used as a function, then it should be used as a
> function.

function;

is a perfectly good function call. It is used as a function.

It is none of the API's business to claim that it must be called like function(), just because that brings in good memories of C. There are
enough languages that got rid of the obligatory '()'.

> You wouldn't use () on a variable would you (aside from defining
> opCall)?

delegates and function pointers come to mind. But that is besides the point.

> I should think not, and I don't think that () should be left out on a
> function any more than they should be used on a variable. It's sloppy and
> confusing.

We are going to disagree on that. Note that '()' can always be included
as a visual clue if it makes sense. There are however cases where it
does not.

>
> Regardless, TDPL calls for strict property enforcement, so that's where we're
> headed.
>

I have heard that rumour, but TDPL wisely specifies the behaviour of
the @property attribute as follows:

'In particular "property" is recognized by the the compiler
and signals the fact that the function bearing such an attribute must be called without the trailing ().'

That is exactly the behaviour I described.

Note that this sentence includes the notion of _calling a function_
without the trailing () and it even seems to express that the trailing
() is usually optional.

So TDPL actually describes a subset of what I have in mind. (it seems
to leave out the function = argument case completely.) We should
therefore change where we are headed.


July 10, 2012
On 2012-07-09 22:16, Andrei Alexandrescu wrote:

> 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.

Is that by design or something that can be fixed?

> To fix the example, write
>
> auto bar = foo.chain(["bar"]);

I think that's an ugly workaround.

>> 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

"Clear as it goes" WTF? Are you nuts? It's an insanly bad error message, I have no "r" in my code. Is it too much to ask to be able to sort a range?

This just proves that std.algorithm is complicated to use. It's very unintuitive.

What I really want is this, but ranges doesn't work like that:

Foo f = Foo();
Foo[] foos = [f];
string[] = foos.map!(x => "foo");
string[] bar = foo ~= "foo";

And:

string[] str = ["foo", "bar"].map!(x => x);
string[] f = str.sort();

-- 
/Jacob Carlborg
July 10, 2012
On 2012-07-09 22:23, Ali Çehreli wrote:

> 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.

If I first have to convert it to an array, then sort and then convert it to an array again. Isn't that missing the whole point of ranges.

-- 
/Jacob Carlborg
July 10, 2012
On 2012-07-09 23:00, Timon Gehr wrote:

> 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.

Are you saying I can't sort a range that comes from "map"? To me it seems like std.algorithm and ranges are a complete failure.

-- 
/Jacob Carlborg
July 10, 2012
On 10-Jul-12 10:54, Jacob Carlborg wrote:
> On 2012-07-09 23:00, Timon Gehr wrote:
>
>> 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.
>
> Are you saying I can't sort a range that comes from "map"? To me it
> seems like std.algorithm and ranges are a complete failure.
>

Can you do it in other languages?

-- 
Dmitry Olshansky


July 10, 2012
On Tuesday, July 10, 2012 08:51:29 Jacob Carlborg wrote:
> On 2012-07-09 22:23, Ali Çehreli wrote:
> > 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.
> 
> If I first have to convert it to an array, then sort and then convert it to an array again. Isn't that missing the whole point of ranges.

The problem is that map is lazy, so it can't be a random access range, and sort requires a random access range. If map were eager, it would just be creating an array anyway. But you don't need to convert it to an array again after sorting it. sort returns a SortedRange so that functions such as find can know that it's sorted and take advantage of it, but it sorts in place (SortedRange is just a wrapper around the range which was passed in and copies no data), so once you've called sort on your array, it's sorted. You can just ignore the return type if you're not looking to pass it to a function which would take advantage of the fact that it's sorted. But since SortedRange _isn't_ lazy (it's just a wrapper around the newly sorted original range, after all), it's still a random access range and will work with functions which require that (unlike map).

You only end up with a range with fewer capabilities than the original when the algorithm itself intrinsicly requires it, and that sort of range is generally lazy (since it's more efficient that way, and making it non-lazy would be equivalent to wrapping it in a call to array anyway).

- Jonathan M Davis