www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - UDAs on Enum Members: Does it require a DIP?

reply Michael V. Franklin <slavo5150 yahoo.com> writes:
Apparently user-defined attributes are not permitted on enum 
members.

Issue is documented here:  
https://issues.dlang.org/show_bug.cgi?id=9701
Pull request implementing the feature is here: 
https://github.com/dlang/dmd/pull/6161

The pull request seems to have stalled over how to get the 
feature approved.  Some consider it an oversight in the 
implementation of UDAs.  Others consider it a language change.  
What's the official word?  Does it require a DIP?

Thanks,
Mike
Nov 19
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, November 19, 2017 13:35:13 Michael V. Franklin via Digitalmars-d 
wrote:
 Apparently user-defined attributes are not permitted on enum
 members.

 Issue is documented here:
 https://issues.dlang.org/show_bug.cgi?id=9701
 Pull request implementing the feature is here:
 https://github.com/dlang/dmd/pull/6161

 The pull request seems to have stalled over how to get the
 feature approved.  Some consider it an oversight in the
 implementation of UDAs.  Others consider it a language change.
 What's the official word?  Does it require a DIP?
It isn't specific to UDAs. You can't put _any_ attributes on enums - including something like deprecated (though to be fair, not many attributes would make sense on an enum member). https://issues.dlang.org/show_bug.cgi?id=9395 - Jonathan M Davis
Nov 19
parent Michael V. Franklin <slavo5150 yahoo.com> writes:
On Sunday, 19 November 2017 at 15:57:58 UTC, Jonathan M Davis 
wrote:

 It isn't specific to UDAs. You can't put _any_ attributes on 
 enums - including something like deprecated (though to be fair, 
 not many attributes would make sense on an enum member).

 https://issues.dlang.org/show_bug.cgi?id=9395
Indeed. That precise use case showed up recently in this PR: https://github.com/dlang/dmd/pull/7303/files Mike
Nov 19
prev sibling next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. Franklin 
wrote:
 Apparently user-defined attributes are not permitted on enum 
 members.

 Issue is documented here:  
 https://issues.dlang.org/show_bug.cgi?id=9701
 Pull request implementing the feature is here: 
 https://github.com/dlang/dmd/pull/6161

 The pull request seems to have stalled over how to get the 
 feature approved.  Some consider it an oversight in the 
 implementation of UDAs.  Others consider it a language change.  
 What's the official word?  Does it require a DIP?

 Thanks,
 Mike
I remember Johan Engelen doing something about this, can't remember if it was LDC or DMD.
Nov 19
prev sibling next sibling parent reply Michael V. Franklin <slavo5150 yahoo.com> writes:
On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. Franklin 
wrote:
 Apparently user-defined attributes are not permitted on enum 
 members.

 Issue is documented here:  
 https://issues.dlang.org/show_bug.cgi?id=9701
 Pull request implementing the feature is here: 
 https://github.com/dlang/dmd/pull/6161

 The pull request seems to have stalled over how to get the 
 feature approved.  Some consider it an oversight in the 
 implementation of UDAs.  Others consider it a language change.  
 What's the official word?  Does it require a DIP?
Bumping this thread. I'm still hoping for an official answer to this. Walter and/or Andrei, Is the lack of support for attributes on `enum` members an implementation oversight? Is a DIP required to move the implementation forward? Thanks, Mike
Nov 27
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/27/2017 05:43 AM, Michael V. Franklin wrote:
 On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. Franklin wrote:
 Apparently user-defined attributes are not permitted on enum members.

 Issue is documented here: https://issues.dlang.org/show_bug.cgi?id=9701
 Pull request implementing the feature is here: 
 https://github.com/dlang/dmd/pull/6161

 The pull request seems to have stalled over how to get the feature 
 approved.  Some consider it an oversight in the implementation of 
 UDAs.  Others consider it a language change. What's the official 
 word?  Does it require a DIP?
Bumping this thread.  I'm still hoping for an official answer to this. Walter and/or Andrei, Is the lack of support for attributes on `enum` members an implementation oversight? Is a DIP required to move the implementation forward? Thanks, Mike
Hi Mike, this forum is not an appropriate place for requesting official answers. We don't scan the forums looking for matters that need attention. Feel free to send email to Walter and myself, and that will get answered. Thanks! -- Andrei
Nov 27
parent reply John <j t.com> writes:
On Monday, 27 November 2017 at 17:48:35 UTC, Andrei Alexandrescu 
wrote:
 Hi Mike, this forum is not an appropriate place for requesting 
 official answers. We don't scan the forums looking for matters 
 that need attention. Feel free to send email to Walter and 
 myself, and that will get answered. Thanks! -- Andrei
Someone seems to disagree with you in that regard. https://forum.dlang.org/post/ouqgln$1chr$1 digitalmars.com Not only did it get your attention but you didn't even bother addressing it!
Nov 27
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, November 28, 2017 00:15:24 John via Digitalmars-d wrote:
 On Monday, 27 November 2017 at 17:48:35 UTC, Andrei Alexandrescu

 wrote:
 Hi Mike, this forum is not an appropriate place for requesting
 official answers. We don't scan the forums looking for matters
 that need attention. Feel free to send email to Walter and
 myself, and that will get answered. Thanks! -- Andrei
Someone seems to disagree with you in that regard. https://forum.dlang.org/post/ouqgln$1chr$1 digitalmars.com Not only did it get your attention but you didn't even bother addressing it!
There is a definite difference between posting stuff in the newsgroup to get attention brought to something and posting in the newsgroup to get an official answer on something from Walter or Andrei. - Jonathan M Davis
Nov 27
next sibling parent John <j t.com> writes:
On Tuesday, 28 November 2017 at 01:49:19 UTC, Jonathan M Davis 
wrote:
 On Tuesday, November 28, 2017 00:15:24 John via Digitalmars-d 
 wrote:
 On Monday, 27 November 2017 at 17:48:35 UTC, Andrei 
 Alexandrescu

 wrote:
 Hi Mike, this forum is not an appropriate place for 
 requesting official answers. We don't scan the forums 
 looking for matters that need attention. Feel free to send 
 email to Walter and myself, and that will get answered. 
 Thanks! -- Andrei
Someone seems to disagree with you in that regard. https://forum.dlang.org/post/ouqgln$1chr$1 digitalmars.com Not only did it get your attention but you didn't even bother addressing it!
There is a definite difference between posting stuff in the newsgroup to get attention brought to something and posting in the newsgroup to get an official answer on something from Walter or Andrei. - Jonathan M Davis
Not really, they can post the official answer on the github issue, that was brought to their attention through the forums. Him asking for an official answer is kind of irrelevant. Something was being neglected, and attention has been brought to it.
Nov 28
prev sibling parent Michael V. Franklin <slavo5150 yahoo.com> writes:
On Tuesday, 28 November 2017 at 01:49:19 UTC, Jonathan M Davis 
wrote:

 There is a definite difference between posting stuff in the 
 newsgroup to get attention brought to something and posting in 
 the newsgroup to get an official answer on something from 
 Walter or Andrei.
My question was on behalf of everyone, so that is why I posted it to the forum. I think Andrei was just trying to say that such questions are likely to be overlooked on the forum, so it is best to send an e-mail. And that's fine with me. Mike
Nov 28
prev sibling parent reply Michael V. Franklin <slavo5150 yahoo.com> writes:
On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. Franklin 
wrote:

 What's the official word?  Does it require a DIP?
For those who might want to know, Walter has informed me that this change will require a DIP. I already have two DIPs in the queue right now, so I wouldn't mind if someone else wrote it. But, absent any volunteers, I would welcome all of you to reply to this thread with some use cases where you might find UDAs or other attributes useful on enum members. Deprecation and serialization have already been mentioned, but it'd be impossible for me to imagine all the different ways users might find this feature useful. Thanks, Mike
Nov 27
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2017-11-28 03:20, Michael V. Franklin wrote:

 For those who might want to know, Walter has informed me that this 
 change will require a DIP.
That's unfortunate. It should be the opposite, a DIP on why enum members should not support attributes. It goes against consistency (turtles all the way down). -- /Jacob Carlborg
Nov 28
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, November 28, 2017 18:24:27 Jacob Carlborg via Digitalmars-d 
wrote:
 On 2017-11-28 03:20, Michael V. Franklin wrote:
 For those who might want to know, Walter has informed me that this
 change will require a DIP.
That's unfortunate. It should be the opposite, a DIP on why enum members should not support attributes. It goes against consistency (turtles all the way down).
For better or worse, Walter and Andrei seem to have gotten into a mode where just about any language change which isn't an outright bug fix requires a DIP. And a lack of turtles all the way down someplace is not really a bug fix (especially since it's sometimes debatable as to whether it's desirable in a particular case or whether something actually qualifies as being an issue with turtles all the way down; it's not always clearcut). However, a lack of consistency _is_ often a good argument - particularly if it's a lack of turtles all the way down consistency; arguments along those lines are how we ended up with stuff like local imports. So, if it's really that clear that enums really should be allowed to have attributes, then the DIP will probably be accepted. - Jonathan M Davis
Nov 28
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Tuesday, 28 November 2017 at 02:20:15 UTC, Michael V. Franklin 
wrote:
 On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. 
 Franklin wrote:

 What's the official word?  Does it require a DIP?
For those who might want to know, Walter has informed me that this change will require a DIP. I already have two DIPs in the queue right now, so I wouldn't mind if someone else wrote it. But, absent any volunteers, I would welcome all of you to reply to this thread with some use cases where you might find UDAs or other attributes useful on enum members. Deprecation and serialization have already been mentioned, but it'd be impossible for me to imagine all the different ways users might find this feature useful. Thanks, Mike
I'd be interested in working on a DIP like this Michael, but I also want to expand the scope to allowing UDAs on function arguments as well. We should have some solid use cases in mind; let's take this to private email.
Nov 28
next sibling parent reply Seb <seb wilzba.ch> writes:
On Tuesday, 28 November 2017 at 19:38:44 UTC, Meta wrote:
 On Tuesday, 28 November 2017 at 02:20:15 UTC, Michael V. 
 Franklin wrote:
 On Sunday, 19 November 2017 at 13:35:13 UTC, Michael V. 
 Franklin wrote:

 What's the official word?  Does it require a DIP?
For those who might want to know, Walter has informed me that this change will require a DIP. I already have two DIPs in the queue right now, so I wouldn't mind if someone else wrote it. But, absent any volunteers, I would welcome all of you to reply to this thread with some use cases where you might find UDAs or other attributes useful on enum members. Deprecation and serialization have already been mentioned, but it'd be impossible for me to imagine all the different ways users might find this feature useful. Thanks, Mike
I'd be interested in working on a DIP like this Michael, but I also want to expand the scope to allowing UDAs on function arguments as well. We should have some solid use cases in mind; let's take this to private email.
UDAs for function arguments would be really awesome to have. Just imagine how nice the Vibe.d web routes would look like: auto postUser( body User user, errors Errors errors) Instead of: body("user") errorDisplay auto postUsers(User _user, string _error) Or: path("/users/:id") auto getUser( urlParam string id, queryParam int page, auth User user) Instead of: path("/users/:id") queryParam("page") before!authenticate("user") auto getUsers(string _id, int page, User user) (This is pseudo-syntax as I write this from my phone).
Nov 29
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2017-11-29 13:53, Seb wrote:

 UDAs for function arguments would be really awesome to have. Just 
 imagine how nice the Vibe.d web routes would look like:
 
 auto postUser( body User user,  errors Errors errors)
 
 Instead of:
  body("user")
  errorDisplay
 auto postUsers(User _user, string  _error)
 
 
 
 Or:
 
  path("/users/:id")
 auto getUser( urlParam string id,  queryParam int page,  auth User user)
 
 Instead of:
 
  path("/users/:id")
  queryParam("page")
  before!authenticate("user")
 auto getUsers(string _id, int page, User user)
 
 
 (This is pseudo-syntax as I write this from my phone).
Yeah, that would be nice. I had another use case in mind as well, for DStep. Clang supports nullability attributes [1] which could be translated to UDAs. They would do anything but would be more for documentation purpose. I guess external tools could be built to actually do something useful with the attributes. Example: In C: int fetch(int * _Nonnull ptr); In D: int fetch( Nonnull int* ptr); [1] https://clang.llvm.org/docs/AttributeReference.html#nullability-attributes -- /Jacob Carlborg
Nov 29
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/29/2017 07:53 AM, Seb wrote:
 UDAs for function arguments would be really awesome to have.
They should be part of the same DIP. -- Andrei
Nov 29
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 29.11.2017 17:21, Andrei Alexandrescu wrote:
 On 11/29/2017 07:53 AM, Seb wrote:
 UDAs for function arguments would be really awesome to have.
They should be part of the same DIP. -- Andrei
More generally, any declaration should ideally support UDAs. One issue with UDAs on function arguments is that function types will then have embedded UDAs, so the DIP should specify how that works.
Nov 29
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/29/17 11:45 AM, Timon Gehr wrote:
 On 29.11.2017 17:21, Andrei Alexandrescu wrote:
 On 11/29/2017 07:53 AM, Seb wrote:
 UDAs for function arguments would be really awesome to have.
They should be part of the same DIP. -- Andrei
More generally, any declaration should ideally support UDAs. One issue with UDAs on function arguments is that function types will then have embedded UDAs, so the DIP should specify how that works.
Wouldn't it work the same as this? ("foo") struct S { } void main() { import std.stdio; ("bar") S s1; S s2; writeln(__traits(getAttributes, s1)); // bar writeln(__traits(getAttributes, typeof(s1))); // foo writeln(__traits(getAttributes, s2)); // (nothing) writeln(__traits(getAttributes, typeof(s2))); // foo } -Steve
Nov 29
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 29.11.2017 17:58, Steven Schveighoffer wrote:
 On 11/29/17 11:45 AM, Timon Gehr wrote:
 On 29.11.2017 17:21, Andrei Alexandrescu wrote:
 On 11/29/2017 07:53 AM, Seb wrote:
 UDAs for function arguments would be really awesome to have.
They should be part of the same DIP. -- Andrei
More generally, any declaration should ideally support UDAs. One issue with UDAs on function arguments is that function types will then have embedded UDAs, so the DIP should specify how that works.
Wouldn't it work the same as this? ("foo") struct S { } void main() {     import std.stdio;     ("bar") S s1;     S s2;     writeln(__traits(getAttributes, s1));         // bar     writeln(__traits(getAttributes, typeof(s1))); // foo     writeln(__traits(getAttributes, s2));         // (nothing)     writeln(__traits(getAttributes, typeof(s2))); // foo } -Steve
I don't understand what you mean. Function types _contain_ parameter declarations. (Including attributes and default initializers.)
Nov 29
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/29/17 12:20 PM, Timon Gehr wrote:
 
 I don't understand what you mean. Function types _contain_ parameter 
 declarations. (Including attributes and default initializers.)
I too, am confused. I thought you meant that the types of the parameters would have attributes that might conflict/merge with the attributes declared on the parameters. So maybe a snippet of code to further explain your concern? -Steve
Nov 29
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 29.11.2017 19:18, Steven Schveighoffer wrote:
 On 11/29/17 12:20 PM, Timon Gehr wrote:
 I don't understand what you mean. Function types _contain_ parameter 
 declarations. (Including attributes and default initializers.)
I too, am confused. I thought you meant that the types of the parameters would have attributes that might conflict/merge with the attributes declared on the parameters. So maybe a snippet of code to further explain your concern? -Steve
struct attribute1{} struct attribute2{} int foo( attribute1 int x){ return x; } int bar( attribute2 int y){ return y; } pragma(msg, typeof(&foo)); // int function( attribute1 int x)? pragam(msg, typeof(&bar)); // int function( attribute2 int x)? auto apply(F,A)(F fun,A arg){ pragma(msg, F); // ? (instantiations below) return fun(arg); } void main(){ apply(&foo,1); // one instantiation apply(&bar,1); // second instantiation, or same instance? } auto weird(){ int x; void foo( x int y){} return &foo; } pragma(msg, typeof(weird())); // ?
Nov 29
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/29/17 2:01 PM, Timon Gehr wrote:

OK, now I get what you are saying. In the same vein, I tested applying 
attributes to functions themselves:

 ("a") int fun() { return 0; }
pragma(msg, typeof(&fun)); // int function()

 ("b") int gun() { return 1; }
pragma(msg, typeof(&gun)); // int function()

void main()
{
   auto f = &fun;
   f = &gun; // works
}

Given that, it seems attributes play no part in the type itself, they 
are just metadata in the compiler.

I would say:

 
 struct attribute1{}
 struct attribute2{}
 
 int foo( attribute1 int x){ return x; }
 int bar( attribute2 int y){ return y; }
 
 pragma(msg, typeof(&foo)); // int function( attribute1 int x)?
int function(int)
 pragam(msg, typeof(&bar)); // int function( attribute2 int x)?
same
 
 auto apply(F,A)(F fun,A arg){
      pragma(msg, F); // ? (instantiations below)
same
      return fun(arg);
 }
 
 void main(){
      apply(&foo,1); // one instantiation
      apply(&bar,1); // second instantiation, or same instance?
same instance
 }
 
 auto weird(){
      int x;
      void foo( x int y){}
      return &foo;
 }
 
 pragma(msg, typeof(weird())); // ?
void delegate(int) -Steve
Nov 29
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 29.11.2017 20:49, Steven Schveighoffer wrote:
 On 11/29/17 2:01 PM, Timon Gehr wrote:
 
 OK, now I get what you are saying. In the same vein, I tested applying 
 attributes to functions themselves:
 
  ("a") int fun() { return 0; }
 pragma(msg, typeof(&fun)); // int function()
 
  ("b") int gun() { return 1; }
 pragma(msg, typeof(&gun)); // int function()
 
 void main()
 {
    auto f = &fun;
    f = &gun; // works
 }
 
 Given that, it seems attributes play no part in the type itself, they 
 are just metadata in the compiler.
Well, I think the case of UDAs on parameters is closer to: struct S{ ("a") int x1; ("b") int x2; } The attributes on x1 and x2 are indeed part of the type S, even if the attributes on S itself are not. If we go with "UDAs on parameters are not part of the function type", how to you get the UDAs of the parameters of some function?
Nov 29
next sibling parent John <j t.com> writes:
On Wednesday, 29 November 2017 at 21:46:51 UTC, Timon Gehr wrote:
 On 29.11.2017 20:49, Steven Schveighoffer wrote:
 On 11/29/17 2:01 PM, Timon Gehr wrote:
 
 OK, now I get what you are saying. In the same vein, I tested 
 applying attributes to functions themselves:
 
  ("a") int fun() { return 0; }
 pragma(msg, typeof(&fun)); // int function()
 
  ("b") int gun() { return 1; }
 pragma(msg, typeof(&gun)); // int function()
 
 void main()
 {
    auto f = &fun;
    f = &gun; // works
 }
 
 Given that, it seems attributes play no part in the type 
 itself, they are just metadata in the compiler.
Well, I think the case of UDAs on parameters is closer to: struct S{ ("a") int x1; ("b") int x2; } The attributes on x1 and x2 are indeed part of the type S, even if the attributes on S itself are not. If we go with "UDAs on parameters are not part of the function type", how to you get the UDAs of the parameters of some function?
The function would have to be passed directly to __traits() to get the UDA. If passed to a function, it would have to be via alias: void func( attr int param) { } void test(alias f)() { writeln(getParameterAttr!(f, 0)); // or however to implement getting the attribute } test!func(); // prints attr
Nov 29
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/29/17 4:46 PM, Timon Gehr wrote:
 On 29.11.2017 20:49, Steven Schveighoffer wrote:
 On 11/29/17 2:01 PM, Timon Gehr wrote:

 OK, now I get what you are saying. In the same vein, I tested applying 
 attributes to functions themselves:

  ("a") int fun() { return 0; }
 pragma(msg, typeof(&fun)); // int function()

  ("b") int gun() { return 1; }
 pragma(msg, typeof(&gun)); // int function()

 void main()
 {
    auto f = &fun;
    f = &gun; // works
 }

 Given that, it seems attributes play no part in the type itself, they 
 are just metadata in the compiler.
Well, I think the case of UDAs on parameters is closer to: struct S{     ("a") int x1;     ("b") int x2; } The attributes on x1 and x2 are indeed part of the type S, even if the attributes on S itself are not.
Right, but unlike functions, you can't make another "overload" of a struct.
 
 If we go with "UDAs on parameters are not part of the function type", 
 how to you get the UDAs of the parameters of some function?
Looking at std.traits, it looks like we use this mechanism to get everything: int func(int param1) static if(is(typeof(func) F == __parameters)) { static assert(is(typeof(F[0]) == int)); static assert(__traits(identifier, F[0]) == "param1"); } This is how vibe.d associates the function-level attributes with the name of the parameter. It wouldn't be a giant leap to make this work with attributes as well. -Steve
Nov 29
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 30.11.2017 00:23, Steven Schveighoffer wrote:
 On 11/29/17 4:46 PM, Timon Gehr wrote:
 On 29.11.2017 20:49, Steven Schveighoffer wrote:
 On 11/29/17 2:01 PM, Timon Gehr wrote:

 OK, now I get what you are saying. In the same vein, I tested 
 applying attributes to functions themselves:

  ("a") int fun() { return 0; }
 pragma(msg, typeof(&fun)); // int function()

  ("b") int gun() { return 1; }
 pragma(msg, typeof(&gun)); // int function()

 void main()
 {
    auto f = &fun;
    f = &gun; // works
 }

 Given that, it seems attributes play no part in the type itself, they 
 are just metadata in the compiler.
Well, I think the case of UDAs on parameters is closer to: struct S{      ("a") int x1;      ("b") int x2; } The attributes on x1 and x2 are indeed part of the type S, even if the attributes on S itself are not.
Right, but unlike functions, you can't make another "overload" of a struct. ...
You also cannot make another overload of a function type.
 If we go with "UDAs on parameters are not part of the function type", 
 how to you get the UDAs of the parameters of some function?
Looking at std.traits, it looks like we use this mechanism to get everything: int func(int param1) static if(is(typeof(func) F == __parameters)) {     static assert(is(typeof(F[0]) == int));     static assert(__traits(identifier, F[0]) == "param1"); } This is how vibe.d associates the function-level attributes with the name of the parameter.
This works because the name of the parameter is part of the function type. Default arguments are in there, too.
 ...
 It wouldn't be a giant leap to make this work with attributes as well.
 
 -Steve
How will this work if typeof(func) does not contain the attributes?
Nov 30
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/30/17 3:26 AM, Timon Gehr wrote:
 On 30.11.2017 00:23, Steven Schveighoffer wrote:
 Looking at std.traits, it looks like we use this mechanism to get 
 everything:

 int func(int param1)

 static if(is(typeof(func) F == __parameters))
 {
      static assert(is(typeof(F[0]) == int));
      static assert(__traits(identifier, F[0]) == "param1");
 }

 This is how vibe.d associates the function-level attributes with the 
 name of the parameter.
This works because the name of the parameter is part of the function type. Default arguments are in there, too.
I'm not going to claim authority here, you would know more than me. But while it does seem to affect the type, it doesn't seem to affect any of the things you are concerned about: int fun(int x) { return 1; } pragma(msg, typeof(&fun)); // int function(int x) int gun(int y) { return 1; } pragma(msg, typeof(&gun)); // int function(int y) pragma(msg, is(typeof(&fun) == typeof(&gun))); // true, types are the "same" template printType(T) { pragma(msg, T); // int function(int) (and only prints once) enum printType = true; // to shut up compiler } auto x = printType!(typeof(&fun)); auto y = printType!(typeof(&gun)); // same instantiation
 It wouldn't be a giant leap to make this work with attributes as well.
How will this work if typeof(func) does not contain the attributes?
I guess it has to, in the same way it "contains" the names and everything else. I just didn't realize how it works. -Steve
Nov 30
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 30.11.2017 15:19, Steven Schveighoffer wrote:
 On 11/30/17 3:26 AM, Timon Gehr wrote:
 On 30.11.2017 00:23, Steven Schveighoffer wrote:
 Looking at std.traits, it looks like we use this mechanism to get 
 everything:

 int func(int param1)

 static if(is(typeof(func) F == __parameters))
 {
      static assert(is(typeof(F[0]) == int));
      static assert(__traits(identifier, F[0]) == "param1");
 }

 This is how vibe.d associates the function-level attributes with the 
 name of the parameter.
This works because the name of the parameter is part of the function type. Default arguments are in there, too.
I'm not going to claim authority here, you would know more than me. But while it does seem to affect the type, it doesn't seem to affect any of the things you are concerned about: int fun(int x) { return 1; } pragma(msg, typeof(&fun)); // int function(int x) int gun(int y) { return 1; } pragma(msg, typeof(&gun)); // int function(int y) pragma(msg, is(typeof(&fun) == typeof(&gun))); // true, types are the "same" ...
Historical context: https://issues.dlang.org/show_bug.cgi?id=3866 http://forum.dlang.org/post/mailman.1421.1346020012.31962.digitalmars-d puremagic.com
 template printType(T)
 {
      pragma(msg, T); // int function(int) (and only prints once)
      enum printType = true; // to shut up compiler
 }
 auto x = printType!(typeof(&fun));
 auto y = printType!(typeof(&gun)); // same instantiation
 
 It wouldn't be a giant leap to make this work with attributes as well.
How will this work if typeof(func) does not contain the attributes?
I guess it has to, in the same way it "contains" the names and everything else. I just didn't realize how it works. -Steve
Ok. I think that makes sense. Note that non-user-defined attributes are not removed though.
Nov 30
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 29.11.2017 20:49, Steven Schveighoffer wrote:
 
 I would say:
 
 struct attribute1{}
 struct attribute2{}

 int foo( attribute1 int x){ return x; }
 int bar( attribute2 int y){ return y; }

 pragma(msg, typeof(&foo)); // int function( attribute1 int x)?
int function(int) ...
Your suggestion is missing the parameter name.
  ...
 auto weird(){
      int x;
      void foo( x int y){}
      return &foo;
 }

 pragma(msg, typeof(weird())); // ?
void delegate(int) -Steve
Just noticed this: auto weird(){ int x=3; int foo(int y=x){ return y; } return &foo; } pragma(msg, typeof(weird)); // int delegate(int y = x) I.e., we have "Voldemort initializers".
Nov 30
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/30/17 3:34 AM, Timon Gehr wrote:
 On 29.11.2017 20:49, Steven Schveighoffer wrote:
 I would say:

 struct attribute1{}
 struct attribute2{}

 int foo( attribute1 int x){ return x; }
 int bar( attribute2 int y){ return y; }

 pragma(msg, typeof(&foo)); // int function( attribute1 int x)?
int function(int) ...
Your suggestion is missing the parameter name.
Yes, I didn't actually test this code, my version was just looking at what happened when attributes were assigned to a function. So I didn't bother putting in parameters, and assumed just the type would come through :)
  ...
 auto weird(){
      int x;
      void foo( x int y){}
      return &foo;
 }

 pragma(msg, typeof(weird())); // ?
void delegate(int)
Just noticed this: auto weird(){      int x=3;      int foo(int y=x){ return y; }      return &foo; } pragma(msg, typeof(weird)); // int delegate(int y = x) I.e., we have "Voldemort initializers".
IMO, whatever mechanism is doing this, it's not really part of the type, but it is part of the type. I think we should consider reworking how this works in the compiler, I don't like the way it's done. It's too fragile and inconsistent. -Steve
Nov 30
prev sibling parent Meta <jared771 gmail.com> writes:
On Wednesday, 29 November 2017 at 16:45:04 UTC, Timon Gehr wrote:
 On 29.11.2017 17:21, Andrei Alexandrescu wrote:
 On 11/29/2017 07:53 AM, Seb wrote:
 UDAs for function arguments would be really awesome to have.
They should be part of the same DIP. -- Andrei
More generally, any declaration should ideally support UDAs. One issue with UDAs on function arguments is that function types will then have embedded UDAs, so the DIP should specify how that works.
You have much more experience in how compilers work on the implementation level than me. What semantics are possible? It makes sense to me that UDAs on function arguments should only be for documentation/reflection purposes. Therefore: int fun( Nonnull Object o); Is considered to be equivalent to: int fun(Object o); And similarly: import std.traits; Parameters!fun -> (Object), not ( Nonnull Object) However: int fun( Nonnull Object o) { static if (is(typeof(fun) Params == __parameters)) { static foreach (p; Params) { pragma(msg, __traits(getUDAs, p)); //Should print Nonnull } } } Unfortunately I don't think we can have both as that would mean that UDAs would have to be part of the function signature. Is there a way around this?
Nov 29
prev sibling parent Michael V. Franklin <slavo5150 yahoo.com> writes:
On Tuesday, 28 November 2017 at 19:38:44 UTC, Meta wrote:

 I'd be interested in working on a DIP like this Michael, but I 
 also want to expand the scope to allowing UDAs on function 
 arguments as well. We should have some solid use cases in mind; 
 let's take this to private email.
I'm on IRC almost daily under the alias JinShil. Feel free to take this DIP and run with it. I don't know if I would be much help anyway as I personally don't have a use case for this feature; it just seems like an implementation oversight to me. That's why I asked for others to submit use cases. That being said, having just finished a recent MVC ASP.Net Core project, I realize Seb's web-routes would be an outstanding use case; I don't know why it didn't occur to me. Just further evidence I may not be the right person to advocate for this feature. ORM also occurred to me as a potential use case. Mike
Nov 29