November 06, 2012
Enjoying playing with the new stuff.

UDAs appear to work on class, struct and global methods, but not interface methods. Any reason for the omission? Would be great to have them on interface methods too - for example to define COM dispids.
November 06, 2012
On 11/6/2012 9:01 AM, deadalnix wrote:
> Le 06/11/2012 17:37, Walter Bright a écrit :
>> On 11/6/2012 8:29 AM, deadalnix wrote:
>>> In addition, this is [] thing will require lookahead when parsing to
>>> detect if
>>> we have an expression (array literal) or a declaration.
>>
>> Not really, as an array literal starting an expression is kinda
>> meaningless,
>
> Not with UFCS.

You have a point.
November 06, 2012
On 11/6/2012 9:00 AM, dennis luehring wrote:
> 1. what if my needs are beyond D?
>
> for example my idl allows me to define a type based query source for parameters
>
> CalculateStuff( TypeX [source="\\placement\(typeA|typeB|typeC)"] my_usage )
>
> this defines the source of assignable objects to this method

Has this capability ever been used?


> 2. what is the reason for stopping right before parameters? (except less coding
> on your side)

It adds significant complexity. I don't think it's a good idea to add significant complexity to the language without a compelling use case. It needs to be something more than just being nice.

November 06, 2012
On Tuesday, 6 November 2012 at 16:41:22 UTC, Walter Bright wrote:
> It would be a significant extension, and so I'd like to see a compelling use case first.

What do you consider to be compelling use cases for UDAs on functions?

Going back to the links on the original post, we have:

"I have numerous systems that need to scan the module for things marked accordingly to automate bindings to their respective systems."

Putting them on parameters also helps with this. Script languages have to deal with parameters. Editors might. And, of course, I've already talked about automatic UI generation.


Here's another one: named parameters. Of course, there's D names, but suppose you have to hook into another naming scheme that uses characters that aren't valid D names?

An external system might send you "log-in?user-id=foo". You are doing a library to automatically call a class:

class Handler {
  [ExternalName("log-in")] /* we can do this now */
    void logIn([ExternalName("user-id")] string userId) {}
      /* but the parameter, which is the same concept, doesn't work */
}



November 06, 2012
On 11/6/2012 9:06 AM, deadalnix wrote:> Le 06/11/2012 16:15, Walter Bright a écrit :
>> On 11/6/2012 5:14 AM, Adam D. Ruppe wrote:
>>> Hmmm, it didn't work on the most important place for my use case,
>>> function
>>> parameters:
>>
>> It didn't occur to me to enable that.
>>
>
> It should work everywhere or not work at all.

You can't have @pure attributes on function parameters, either. Parameters don't work like regular declarations, never have, and I don't know of a language where they do. They even have a different grammar.

November 06, 2012
On 11/6/2012 9:07 AM, John Chapman wrote:
> UDAs appear to work on class, struct and global methods, but not interface
> methods. Any reason for the omission? Would be great to have them on interface
> methods too - for example to define COM dispids.

Can you show an example code snippet?
November 06, 2012
On Tuesday, 6 November 2012 at 17:16:34 UTC, Adam D. Ruppe wrote:
>   [ExternalName("log-in")] /* we can do this now */
>     void logIn([ExternalName("user-id")] string userId)


BTW we could conceivably do:

[ExternalName("log-in"),
ParameterAttribute!("userId")(ExternalName("user-id")]
   void logIn(string userId) {}


Where the ParameterAttribute simply matches up the param by name or by position (if you pass an int instead of string) and puts the other argument in that map.

When you scan the function for attributes, you keep your eye open for that ParameterAttribute thingy and match it up in the library.


So if it is too painful to put it in the compiler, we could make it work in the library.
November 06, 2012
Am 06.11.2012 18:14, schrieb Walter Bright:> On 11/6/2012 9:00 AM, dennis luehring wrote:
>> 1. what if my needs are beyond D?
>>
>> for example my idl allows me to define a type based query source for parameters
>>
>> CalculateStuff( TypeX [source="\\placement\(typeA|typeB|typeC)"] my_usage )
>>
>> this defines the source of assignable objects to this method
>
> Has this capability ever been used?

all the while - the complete object-to-object lifecycle of composits etc. is managed by this - no coded object creation is happening

its partially based on the naked object pattern

the next step will be a complete managed(and hopefully more efficient) loading/locking strategy - but still in around 800k lines of C++ :(
November 06, 2012
Le 06/11/2012 18:14, Walter Bright a écrit :
> On 11/6/2012 9:00 AM, dennis luehring wrote:
>> 1. what if my needs are beyond D?
>>
>> for example my idl allows me to define a type based query source for
>> parameters
>>
>> CalculateStuff( TypeX [source="\\placement\(typeA|typeB|typeC)"]
>> my_usage )
>>
>> this defines the source of assignable objects to this method
>
> Has this capability ever been used?
>
>
>> 2. what is the reason for stopping right before parameters? (except
>> less coding
>> on your side)
>
> It adds significant complexity. I don't think it's a good idea to add
> significant complexity to the language without a compelling use case. It
> needs to be something more than just being nice.
>

It remove complexity in the sens it remove special cases.

It indeed add complexity for the compiler.
November 06, 2012
On Tuesday, 6 November 2012 at 17:00:27 UTC, Walter Bright wrote:
> Ok, I ask again, what use case for a UDA is there for function parameters? (Note that IDL isn't it, as D already has enough parameter attributes to support IDL.)

What »IDL« are you referring to here? At least as far as I am aware, IDL usually just refers to an »interface definition language« in general, so I'm not quite sure what you mean if you are talking about »enough to support IDL«.

Actually, the Thrift IDL would be a perfect example of how attributes on parameters can be useful. A simple service definition in a .thrift could look like this:

---
service Calculator {
   i32 calculate(1:i32 a, 2:i32 b, 3:Op op)
}
---

Note that the parameters are given explicit ids, similar to regular struct fields in Thrift, to provide robustness of the generated code against future RPC protocol changes (e.g. addition of parameters).

Currently, the equivalent D code for the interface would look something like this:

---
interface Calculator : SharedService {
  int calculate(int a, int b, Op op);

  enum methodMeta = [
    TMethodMeta(`calculate`,
      [TParamMeta(`a`, 1), TParamMeta(`b`, 2), TParamMeta(`op`, 3)]
    )
  ];
}
---

Being able to assign the IDs in-line using UDAs would make for a much more natural method declaration syntax.

David