www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - map kinds of Ranges

reply bearophile <bearophileHUGS lycos.com> writes:
In Python you are allowed to scan a generator/iterator only once. This D code
has caused me a bug:


import std.stdio, std.algorithm, std.math, std.range, std.random;
int gen(int x) { return uniform(-100, 100); }
void main() {
    auto data = map!gen(iota(10));
    writeln(data); // just a debug print
    writeln(data); // just a debug print
    int result = minPos!((a, b){ return abs(a) < abs(b); })(data).front();
    writeln(result);
}


I think gen() get called every time data() is accessed, so abs(a)<abs(b) gives
bogus results.

I think the result of map() has to become a Forward Range only if the mapping
function is pure (even if iota() here is more than just a Forward Range),
otherwise it's better to make it a Input Range (so you can't use minPos on it,
and this bug doesn't happen).

Bye,
bearophile
May 23 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/23/11 6:42 PM, bearophile wrote:
 In Python you are allowed to scan a generator/iterator only once. This D code
has caused me a bug:


 import std.stdio, std.algorithm, std.math, std.range, std.random;
 int gen(int x) { return uniform(-100, 100); }
 void main() {
      auto data = map!gen(iota(10));
      writeln(data); // just a debug print
      writeln(data); // just a debug print
      int result = minPos!((a, b){ return abs(a)<  abs(b); })(data).front();
      writeln(result);
 }


 I think gen() get called every time data() is accessed, so abs(a)<abs(b) gives
bogus results.

 I think the result of map() has to become a Forward Range only if the mapping
function is pure (even if iota() here is more than just a Forward Range),
otherwise it's better to make it a Input Range (so you can't use minPos on it,
and this bug doesn't happen).

 Bye,
 bearophile

This amount of babysitting would be unacceptable for map. A function can't be pure for a variety of reasons. Andrei
May 23 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-23 19:05, Andrei Alexandrescu wrote:
 On 5/23/11 6:42 PM, bearophile wrote:
 In Python you are allowed to scan a generator/iterator only once. This D
 code has caused me a bug:
 
 
 import std.stdio, std.algorithm, std.math, std.range, std.random;
 int gen(int x) { return uniform(-100, 100); }
 void main() {
 
      auto data = map!gen(iota(10));
      writeln(data); // just a debug print
      writeln(data); // just a debug print
      int result = minPos!((a, b){ return abs(a)<  abs(b);
      })(data).front(); writeln(result);
 
 }
 
 
 I think gen() get called every time data() is accessed, so abs(a)<abs(b)
 gives bogus results.
 
 I think the result of map() has to become a Forward Range only if the
 mapping function is pure (even if iota() here is more than just a
 Forward Range), otherwise it's better to make it a Input Range (so you
 can't use minPos on it, and this bug doesn't happen).
 
 Bye,
 bearophile

This amount of babysitting would be unacceptable for map. A function can't be pure for a variety of reasons.

Setting aside this particular issue with purity, I would very much like to see conditional purity implemented (along with conditional nothrow, conditional safe, etc.), or it's going to be next to impossible to have stuff like map be pure even when it should be able to. I think that conditional attributes for templated functions would _really_ help make attributes such as pure and nothrow properly useable. I'm not sure that they'll ever truly be useful in the general case without conditional attribututes. I keep trying to write range-based code which uses pure and nothrow, and it often just doesn't work. Conditional attributes would fix that. I know that it's been discussed before, but I'd _really_ love to see it actually implemented instead of just discussed. Unfortunately, I have plenty of other stuff to do other than trying to learn the compiler well enough to attempt to implement such a feature myself. Regardless, I agree that enforcing extra conditions based on purity for map would not be good. It would be _far_ too constrictive. You just have to be smart about what functions you give it. If we try too hard to stop people from creating bugs, we'll lose a lot of D's power and elegance. - Jonathan M Davis
May 23 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 5/23/2011 7:33 PM, Jonathan M Davis wrote:
 Setting aside this particular issue with purity, I would very much 
 like to see conditional purity implemented (along with conditional 
 nothrow, conditional  safe, etc.),

http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digital ars.D&artnum=127569 <http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=127569> As much as I like the idea, though, I think a /lot/ of these would be fixed simply with the ability to put metadata/attributes/annotations, instead of introducing new syntax like conditionally_pure, etc. That way, pure, nothrow, safe, etc. could just become attributes that could take in arguments, and it would also simply the syntax of the language a bit, reducing the number of keywords. It would also add one major feature D lacks right now (metadata) that is really helpful in a lot of situations. Thoughts on this?
May 23 2011
next sibling parent reply Mehrdad <wfunction hotmail.com> writes:
On 5/23/2011 8:28 PM, Jonathan M Davis wrote:
 I believe that the best and most likely to be implemented syntax which 
 has been suggested (it was Andrei's idea IIRC) is to simply add 
 optional clauses to attributes. So, instead of pure, you'd do 
 pure(condition). If the condition is true, the templated function it's 
 on is pure. If the condition is false, then the function isn't pure. 
 Don't expect pure to become  pure or nothrow to become  nothrow 
 though. I think that at this point, any attribute which is a keyword 
 is going to stay one, and any attribute that has   on the front of it 
 is going to stay that way as well. - Jonathan M Davis 

Why make the syntax complicated for just a little gain? Wouldn't it kill a lot more birds with one stone if we allow for attributes?
May 23 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 5/23/2011 10:08 PM, Jonathan M Davis wrote:
 On 2011-05-23 22:02, Mehrdad wrote:
 One question: Why make the syntax complicated for just a little gain? 
 Wouldn't it kill a lot more birds with one stone if we allow for 
 attributes? 

attributes can still be added later. Besides, the gain is _enormous_. Without conditional purity, conditional nothrow, conditional safe, etc. most generic functions (including a large portion of Phobos) can never be pure, nothrow, safe, etc. - Jonathan M Davis

said they should be with attributes rather than keywords, because that would somewhat simplify the syntax (fewer keywords, although attribute syntax is added) and unify things. So the question was: Why not make pure, etc. become regular metadata? That way the syntax would likely turn out the same as user-defined attributes.
May 23 2011
parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 5/24/2011 1:51 AM, Jonathan M Davis wrote:
 On 2011-05-23 22:22, Mehrdad wrote:
 On 5/23/2011 10:08 PM, Jonathan M Davis wrote:
 On 2011-05-23 22:02, Mehrdad wrote:
 One question: Why make the syntax complicated for just a little gain?
 Wouldn't it kill a lot more birds with one stone if we allow for
 attributes?

They _are_ attributes. They're just not user-defined attributes. User-defined attributes can still be added later. Besides, the gain is _enormous_. Without conditional purity, conditional nothrow, conditional safe, etc. most generic functions (including a large portion of Phobos) can never be pure, nothrow, safe, etc. - Jonathan M Davis

Wait, what? I never said we shouldn't include conditional stuff, I just said they should be with attributes rather than keywords, because that would somewhat simplify the syntax (fewer keywords, although attribute syntax is added) and unify things. So the question was: Why not make pure, etc. become regular metadata? That way the syntax would likely turn out the same as user-defined attributes.

The decision was made a while ago to make the attributes which are keywords keywords and the ones which start with start with . It was a bit arbitrary, but the decision was made. Changing it now would break a lot of code for little benefit, and I'd be _very_ surprised if you could talk Walter into it. And it's not like an objective decision can really be made about which start with and which don't anyway. Arguments could be made either way for all of them. And honestly, I don't expect that it would be much more complicated (if any more complicated at all) to implement pure(condition) than pure(condition). I don't think that the compiler treats the keyword attributes and the attributes much differently at this point anyway. And even if user-defined attributes were added, I don't think that it would really matter what was done with the keyword attributes and attributes which are built in. They'd likely be acting differently anyway. vs keyword is one of those things that you stand little chance of getting changed in the language at this point. - Jonathan M Davis

So I originally thought that attributes are purely metadata and are not part of the signature of the function, while keywords could (potentially) allow the compiler to generate different code. For example, pure allows the compiler to squash multiple calls to a pure function with the same parameters into a single call. However, this maybe isn't the case. I thought this code wouldn't compile: import std.stdio; import std.conv; int test(int function(int x) nothrow myfunc, int y) { return myfunc(y); } int test1(int x) { if (x == 42) throw new Exception("Uh oh!"); return x + 20; } nothrow int test2(int x) { return x / 20; } void main(string[] argv) { auto y = to!int(argv[1]); writeln(test(&test1, y)); writeln(test(&test2, y)); } This shouldn't compile (as far as I know), whereas if you replaced the "nothrow"s with " safe"s, it would compile. However, it looks like both compile. This looks like a bug. Anyone know off the top of their head if this exists in Bugzilla? Anyway, from an theoretical point of view, attributes purely describe a symbol, while keywords change it's signature. Perhaps I'm not correct though.
May 25 2011
prev sibling next sibling parent KennyTM~ <kennytm gmail.com> writes:
On May 24, 11 11:28, Jonathan M Davis wrote:
 On 2011-05-23 20:18, Mehrdad wrote:
 On 5/23/2011 7:33 PM, Jonathan M Davis wrote:
 Setting aside this particular issue with purity, I would very much
 like to see conditional purity implemented (along with conditional
 nothrow, conditional  safe, etc.),

I'm liking that people are liking the idea. :-) http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group =digitalmars.D&artnum=127569 <http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&gro up=digitalmars.D&artnum=127569> As much as I like the idea, though, I think a /lot/ of these would be fixed simply with the ability to put metadata/attributes/annotations, instead of introducing new syntax like conditionally_pure, etc. That way, pure, nothrow, safe, etc. could just become attributes that could take in arguments, and it would also simply the syntax of the language a bit, reducing the number of keywords. It would also add one major feature D lacks right now (metadata) that is really helpful in a lot of situations. Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

Rather than conditional pure/nothrow/ safe, I suggest simply have a functionAttribute(x), such that: x & 1 <==> pure x & 2 <==> nothrow x & 0x30 <==> safe so that you only need 1 attribute to explicitly take care of all of the propagative attributes import std.traits; functionAttribute(functionAttributes!f & functionAttributes!(x.front)) auto front() const { return f(x.front); } instead of having to repeat the same structure 3 times import std.traits; safe(areAllSafe!(f, x.front)) pure(functionAttributes!f & functionAttributes!x.front & FunctionAttribute.PURE) nothrow(functionAttributes!f & functionAttributes!x.front & FunctionAttribute.NOTHROW) auto front() const { return f(x.front); }
May 23 2011
prev sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

Wouldn't it make sense to follow the same syntax as auto ref? auto pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<) -- Robert http://octarineparrot.com/
May 24 2011
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On May 25, 11 01:25, Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

Wouldn't it make sense to follow the same syntax as auto ref? auto pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

public auto pure auto nothrow auto safe auto ref front() const { return f(x.front); } :p Actually I believe the point of having conditional attribute is to get the most restrictive one, where auto-attribute fit in better than the more generalized alternative. Or we could just have an 'auto' condition to let the compiler choose the most restrictive one. public pure(auto) nothrow(auto) safe(auto) auto ref front() const { return f(x.front); } (still way too long :p)
May 24 2011
prev sibling parent reply Don <nospam nospam.com> writes:
Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

Wouldn't it make sense to follow the same syntax as auto ref? auto pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.
May 25 2011
parent reply Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:
 
 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

The current implementation is incorrect. In a correct implementation auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return
May 25 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-25 08:48, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:
 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:
 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. =20 - Jonathan M Davis =20

=20 pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'. =20

=20 auto ref *is* always ref. =20 -Steve

You're saying this example from the spec shouldn't compile? =20 auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too.

=46rom a quick glance at TDPL, I see no sign of it (or at least, none of th= e=20 pages which the index claim to have auto or ref appear to mention it). My=20 first reaction is to agree with Steve that auto ref must be a reference, bu= t I=20 vaguely recall a discussion about auto ref on a parameter meaning that the= =20 compiler then decided whether the parameter was a ref or not and that Andre= i=20 said that Walter had misunderstood the feature and misimplemented it. I don= 't=20 recall the details though, so I could be wrong. Personally though, I would= =20 have expected auto ref as a return type to mean that the type was always a= =20 reference but that the type of that reference was inferred. =2D Jonathan M Davis
May 25 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/25/11 10:48 AM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve

The example should work. "auto ref" means "ref if possible, otherwise drop it". Andrei
May 25 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/25/11 12:15 PM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 12:19:03 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 5/25/11 10:48 AM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve

The example should work. "auto ref" means "ref if possible, otherwise drop it".

Wait, I thought auto ref was to allow rvalues to be passed by reference? I.e. given the function: void foo(auto ref S s) then you could call foo with an rvalue or an lvalue for s. I swear every time you have an opinion on auto ref it changes :( Or are there two different meanings depending on whether auto ref is a parameter or return value attribute? -Steve

The same principle applies to your example: try ref if it works, otherwise drop it. Andrei
May 25 2011
next sibling parent foobar <foo bar.com> writes:
Andrei Alexandrescu Wrote:

 On 5/25/11 12:15 PM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 12:19:03 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 5/25/11 10:48 AM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve

The example should work. "auto ref" means "ref if possible, otherwise drop it".

Wait, I thought auto ref was to allow rvalues to be passed by reference? I.e. given the function: void foo(auto ref S s) then you could call foo with an rvalue or an lvalue for s. I swear every time you have an opinion on auto ref it changes :( Or are there two different meanings depending on whether auto ref is a parameter or return value attribute? -Steve

The same principle applies to your example: try ref if it works, otherwise drop it. Andrei

I agree with pretty much everyone else on this. This is a horrible syntax which has nothing to do with neither 'auto' nor 'ref'. I propose instead: void foo(drop it like it's hot ref S s); where "drop it like it's hot" is a single lexer token.
May 25 2011
prev sibling parent foobar <foo bar.com> writes:
Andrei Alexandrescu Wrote:

 On 5/25/11 12:15 PM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 12:19:03 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 5/25/11 10:48 AM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve

The example should work. "auto ref" means "ref if possible, otherwise drop it".

Wait, I thought auto ref was to allow rvalues to be passed by reference? I.e. given the function: void foo(auto ref S s) then you could call foo with an rvalue or an lvalue for s. I swear every time you have an opinion on auto ref it changes :( Or are there two different meanings depending on whether auto ref is a parameter or return value attribute? -Steve

The same principle applies to your example: try ref if it works, otherwise drop it. Andrei

I agree with pretty much everyone else on this. This is a horrible syntax which has nothing to do with neither 'auto' nor 'ref'. I propose instead: void foo(drop it like it's hot ref S s); where "drop it like it's hot" is a single lexer token.
May 25 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-23 20:18, Mehrdad wrote:
 On 5/23/2011 7:33 PM, Jonathan M Davis wrote:
 Setting aside this particular issue with purity, I would very much
 like to see conditional purity implemented (along with conditional
 nothrow, conditional  safe, etc.),

I'm liking that people are liking the idea. :-) http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group =digitalmars.D&artnum=127569 <http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&gro up=digitalmars.D&artnum=127569> As much as I like the idea, though, I think a /lot/ of these would be fixed simply with the ability to put metadata/attributes/annotations, instead of introducing new syntax like conditionally_pure, etc. That way, pure, nothrow, safe, etc. could just become attributes that could take in arguments, and it would also simply the syntax of the language a bit, reducing the number of keywords. It would also add one major feature D lacks right now (metadata) that is really helpful in a lot of situations. Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis
May 23 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-23 22:02, Mehrdad wrote:
 On 5/23/2011 8:28 PM, Jonathan M Davis wrote:
 I believe that the best and most likely to be implemented syntax which
 has been suggested (it was Andrei's idea IIRC) is to simply add
 optional clauses to attributes. So, instead of pure, you'd do
 pure(condition). If the condition is true, the templated function it's
 on is pure. If the condition is false, then the function isn't pure.
 Don't expect pure to become  pure or nothrow to become  nothrow
 though. I think that at this point, any attribute which is a keyword
 is going to stay one, and any attribute that has   on the front of it
 is going to stay that way as well. - Jonathan M Davis

One question: Why make the syntax complicated for just a little gain? Wouldn't it kill a lot more birds with one stone if we allow for attributes?

They _are_ attributes. They're just not user-defined attributes. User-defined attributes can still be added later. Besides, the gain is _enormous_. Without conditional purity, conditional nothrow, conditional safe, etc. most generic functions (including a large portion of Phobos) can never be pure, nothrow, safe, etc. - Jonathan M Davis
May 23 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-23 22:22, Mehrdad wrote:
 On 5/23/2011 10:08 PM, Jonathan M Davis wrote:
 On 2011-05-23 22:02, Mehrdad wrote:
 One question: Why make the syntax complicated for just a little gain?
 Wouldn't it kill a lot more birds with one stone if we allow for
 attributes?

They _are_ attributes. They're just not user-defined attributes. User-defined attributes can still be added later. Besides, the gain is _enormous_. Without conditional purity, conditional nothrow, conditional safe, etc. most generic functions (including a large portion of Phobos) can never be pure, nothrow, safe, etc. - Jonathan M Davis

Wait, what? I never said we shouldn't include conditional stuff, I just said they should be with attributes rather than keywords, because that would somewhat simplify the syntax (fewer keywords, although attribute syntax is added) and unify things. So the question was: Why not make pure, etc. become regular metadata? That way the syntax would likely turn out the same as user-defined attributes.

The decision was made a while ago to make the attributes which are keywords keywords and the ones which start with start with . It was a bit arbitrary, but the decision was made. Changing it now would break a lot of code for little benefit, and I'd be _very_ surprised if you could talk Walter into it. And it's not like an objective decision can really be made about which start with and which don't anyway. Arguments could be made either way for all of them. And honestly, I don't expect that it would be much more complicated (if any more complicated at all) to implement pure(condition) than pure(condition). I don't think that the compiler treats the keyword attributes and the attributes much differently at this point anyway. And even if user-defined attributes were added, I don't think that it would really matter what was done with the keyword attributes and attributes which are built in. They'd likely be acting differently anyway. vs keyword is one of those things that you stand little chance of getting changed in the language at this point. - Jonathan M Davis
May 23 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

The current implementation is incorrect. In a correct implementation auto ref *is* always ref. -Steve
May 25 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve
May 25 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I don't think auto ref is in TDPL actually.
May 25 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 25 May 2011 12:19:03 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 5/25/11 10:48 AM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 11:45:30 -0400, Don <nospam nospam.com> wrote:

 Steven Schveighoffer wrote:
 On Wed, 25 May 2011 10:59:46 -0400, Don <nospam nospam.com> wrote:

 Robert Clipsham wrote:
 On 24/05/2011 04:28, Jonathan M Davis wrote:
 Thoughts on this?

I believe that the best and most likely to be implemented syntax which has been suggested (it was Andrei's idea IIRC) is to simply add optional clauses to attributes. So, instead of pure, you'd do pure(condition). If the condition is true, the templated function it's on is pure. If the condition is false, then the function isn't pure. Don't expect pure to become pure or nothrow to become nothrow though. I think that at this point, any attribute which is a keyword is going to stay one, and any attribute that has on the front of it is going to stay that way as well. - Jonathan M Davis

pure, auto nothrow, auto safe etc? (Although I guess that doesn't allow for conditions, nevermind :<)

'auto ref' is one of worst syntax anomalies in the language. It should be a single keyword -- eg, 'autoref' -- it has nothing in common with the other use of 'auto', and it's not necessarily 'ref'.

auto ref *is* always ref. -Steve

You're saying this example from the spec shouldn't compile? auto ref foo() { return 3; } // value return

Yes. Auto ref is specifically to allow passing rvalues as references to functions, not as a template that means either ref or not. At least, that is my understanding from Andrei's description. I don't have a copy of TDPL, but I think it's in there too. -Steve

The example should work. "auto ref" means "ref if possible, otherwise drop it".

Wait, I thought auto ref was to allow rvalues to be passed by reference? I.e. given the function: void foo(auto ref S s) then you could call foo with an rvalue or an lvalue for s. I swear every time you have an opinion on auto ref it changes :( Or are there two different meanings depending on whether auto ref is a parameter or return value attribute? -Steve
May 25 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 25 May 2011 13:21:48 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 5/25/11 12:15 PM, Steven Schveighoffer wrote:
 On Wed, 25 May 2011 12:19:03 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 The example should work. "auto ref" means "ref if possible, otherwise
 drop it".

Wait, I thought auto ref was to allow rvalues to be passed by reference? I.e. given the function: void foo(auto ref S s) then you could call foo with an rvalue or an lvalue for s. I swear every time you have an opinion on auto ref it changes :( Or are there two different meanings depending on whether auto ref is a parameter or return value attribute? -Steve

The same principle applies to your example: try ref if it works, otherwise drop it.

I have brought this up before, and you categorically denied it. If this is the case, then auto ref must generate two different copies of the function, one which takes ref and one which does not. You can't just "drop ref" without having a separate function which is not ref (all accesses to the parameter would be by value vs. by reference). I again am confused about auto ref, and I thought I had figured it out :( See this conversation: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=123664 -Steve
May 25 2011
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-05-25 14:09, Johann MacDonagh wrote:
 On 5/24/2011 1:51 AM, Jonathan M Davis wrote:
 On 2011-05-23 22:22, Mehrdad wrote:
 On 5/23/2011 10:08 PM, Jonathan M Davis wrote:
 On 2011-05-23 22:02, Mehrdad wrote:
 One question: Why make the syntax complicated for just a little gain?
 Wouldn't it kill a lot more birds with one stone if we allow for
 attributes?

They _are_ attributes. They're just not user-defined attributes. User-defined attributes can still be added later. Besides, the gain is _enormous_. Without conditional purity, conditional nothrow, conditional safe, etc. most generic functions (including a large portion of Phobos) can never be pure, nothrow, safe, etc. - Jonathan M Davis

Wait, what? I never said we shouldn't include conditional stuff, I just said they should be with attributes rather than keywords, because that would somewhat simplify the syntax (fewer keywords, although attribute syntax is added) and unify things. So the question was: Why not make pure, etc. become regular metadata? That way the syntax would likely turn out the same as user-defined attributes.

The decision was made a while ago to make the attributes which are keywords keywords and the ones which start with start with . It was a bit arbitrary, but the decision was made. Changing it now would break a lot of code for little benefit, and I'd be _very_ surprised if you could talk Walter into it. And it's not like an objective decision can really be made about which start with and which don't anyway. Arguments could be made either way for all of them. And honestly, I don't expect that it would be much more complicated (if any more complicated at all) to implement pure(condition) than pure(condition). I don't think that the compiler treats the keyword attributes and the attributes much differently at this point anyway. And even if user-defined attributes were added, I don't think that it would really matter what was done with the keyword attributes and attributes which are built in. They'd likely be acting differently anyway. vs keyword is one of those things that you stand little chance of getting changed in the language at this point. - Jonathan M Davis

So I originally thought that attributes are purely metadata and are not part of the signature of the function, while keywords could (potentially) allow the compiler to generate different code. For example, pure allows the compiler to squash multiple calls to a pure function with the same parameters into a single call. However, this maybe isn't the case. I thought this code wouldn't compile: import std.stdio; import std.conv; int test(int function(int x) nothrow myfunc, int y) { return myfunc(y); } int test1(int x) { if (x == 42) throw new Exception("Uh oh!"); return x + 20; } nothrow int test2(int x) { return x / 20; } void main(string[] argv) { auto y = to!int(argv[1]); writeln(test(&test1, y)); writeln(test(&test2, y)); } This shouldn't compile (as far as I know), whereas if you replaced the "nothrow"s with " safe"s, it would compile. However, it looks like both compile. This looks like a bug. Anyone know off the top of their head if this exists in Bugzilla? Anyway, from an theoretical point of view, attributes purely describe a symbol, while keywords change it's signature. Perhaps I'm not correct though.

Function pointers and delegates don't deal with attributes very well at this point. There's at least one or two bugs on the matter already. They tend to work or not work when they shouldn't (mostly work IIRC). In any case, at this point, all of the attributes act like keywords (they aren't keywords though, since they aren't valid attributes). There's really no difference between nothrow and safe except what they do. _All_ of a function's attributes are actually part of its signature (except perhaps for deprecated). The fact that a particular attribute is a keyword while another starts with is very nearly completely arbitrary. If another language has it as a keyword (such as public or const), then it's a keyword, but beyond that, whether a particular attribute is a keyword or is completely arbitrary. IIRC, some of them flipflopped between keyword and , and there was some debate on what should be what, but in the end, I'm not sure that there was much planning with regards to what got and what didn't. seems to have been introduced primarily as a way to avoid creating more keywords. Some of us are hoping that we'll get user-defined attributes at some point, but the attributes don't work that way at all at this point (though I don't see why they couldn't just be considered as reserved attribute names and special-cased by the compiler if and when we get user-defined attributes). So, in the end, keyword vs is pretty arbitrary. Don't try and categorize attributes differently from keyword attributes, because there really is no difference. - Jonathan M Davis
May 25 2011