November 30, 2017
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
November 30, 2017
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
December 01, 2017
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.
January 02, 2018
On Wednesday, 29 November 2017 at 14:23:30 UTC, Michael V. Franklin wrote:
> 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


For those people not following dlang/DIPs yet, Mark stepped up and submitted a DIP for it:

https://github.com/dlang/DIPs/pull/105

And there's also a PR for UDAs on function parameters:

https://github.com/dlang/dmd/pull/7576

So everyone who wants to see this become reality in 2018 -> help to improve the DIP or PR ;-)
1 2 3 4
Next ›   Last »