Thread overview
Syntax for Static Import of User Define Attributes
Jul 27
Dennis
Jul 28
Dennis
Jul 28
ryuukk_
July 27

What is the correct syntax to use a static import of a user-defined-attribute?

Context: Attributes can have names that conflict with local variables. It is desired to use the fully-qualified-name of the attribute to get around this.

Example:

import vibe.data.serialization : name, optional;

class ChatCompletionFunctions {
  @name("name")  // Error: "name" refers to the string, not the attribute @name.
  string name;

  @name("max-tokens")
  int maxTokens;
}

Attempted Fix 1: static imports

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @vibe.data.serialization.name("name")
  ...
}

This produces the error, it seems to be because the @ symbol stops capturing the annotation name at the first dot it encounters.

source/openai/model/ChatCompletionFunctions.d(19,32): Error: unexpected `(` in declarator

Attempted Fix 2: Enclose the entire attribute name in parenthesis.

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @(vibe.data.serialization.name)("name")
  ...
}

This simply gives:

source/openai/model/ChatCompletionFunctions.d(19,34): Error: declaration expected, not `(`

Is static importing of UDAs even supported in the language?

July 27

On Thursday, 27 July 2023 at 21:19:08 UTC, Vijay Nayar wrote:

>

Attempted Fix 2: Enclose the entire attribute name in parenthesis.

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @(vibe.data.serialization.name)("name")
  ...
}

You almost had it. The correct syntax is to enclose the entire attribute (not just the name) in parentheses:

class ChatCompletionFunctions {
  @(vibe.data.serialization.name("name"))
  string name;
}
July 27

On Thursday, 27 July 2023 at 21:19:08 UTC, Vijay Nayar wrote:

>

Attempted Fix 2: Enclose the entire attribute name in parenthesis.

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @(vibe.data.serialization.name)("name")
  ...
}

Try:

@(vibe.data.serialization.name("name"))
July 28

On Thursday, 27 July 2023 at 21:24:44 UTC, Dennis wrote:

>

On Thursday, 27 July 2023 at 21:19:08 UTC, Vijay Nayar wrote:

>

Attempted Fix 2: Enclose the entire attribute name in parenthesis.

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @(vibe.data.serialization.name)("name")
  ...
}

Try:

@(vibe.data.serialization.name("name"))

This one causes a different error, because it invokes the template-argument syntax: https://dlang.org/spec/attribute.html#uda

July 28

On 7/28/23 4:15 AM, Vijay Nayar wrote:

>

On Thursday, 27 July 2023 at 21:24:44 UTC, Dennis wrote:

>

On Thursday, 27 July 2023 at 21:19:08 UTC, Vijay Nayar wrote:

>

Attempted Fix 2: Enclose the entire attribute name in parenthesis.

static import vibe.data.serialization;

class ChatCompletionFunctions {
  @(vibe.data.serialization.name)("name")
  ...
}

Try:

@(vibe.data.serialization.name("name"))

This one causes a different error, because it invokes the template-argument syntax: https://dlang.org/spec/attribute.html#uda

I tried it and it worked for me. The template-argument syntax is normal. It's just a list of types or expressions (i.e. not a function argument list)

What is the error?

-Steve

July 28

On Friday, 28 July 2023 at 11:54:12 UTC, Steven Schveighoffer wrote:

>

On 7/28/23 4:15 AM, Vijay Nayar wrote:

I tried it and it worked for me. The template-argument syntax is normal. It's just a list of types or expressions (i.e. not a function argument list)

What is the error?

-Steve

You're right, I must have tried something slightly different without realizing it. The syntax that works seems to be to enclose the entire fully-qualified-name of the user-defined-attribute along with all its arguments within parentheses.

However, this makes me wonder. Is there any reason why the @ shouldn't recognize the dots in a fully-qualified-name on its own, without the need for parentheses?

July 28

On 7/28/23 8:10 AM, Vijay Nayar wrote:

>

However, this makes me wonder. Is there any reason why the @ shouldn't recognize the dots in a fully-qualified-name on its own, without the need for parentheses?

It might be possible to expand the grammar. It seems very specific to UDAs, as it doesn't just throw out Expression or whatnot. It probably has to do with the spot that it's in (declaration). I'll defer to the compiler experts to decide what makes the most sense.

-Steve

July 28

On Friday, 28 July 2023 at 12:20:05 UTC, Steven Schveighoffer wrote:

>

On 7/28/23 8:10 AM, Vijay Nayar wrote:
It might be possible to expand the grammar. It seems very specific to UDAs, as it doesn't just throw out Expression or whatnot. It probably has to do with the spot that it's in (declaration).

Yes, parsing arbitrary expressions after an @ would result in this:

void f(int x) @att in (x > 0) { }

Being parsed as:

void f(int x) @(att in (x > 0)) { }

And things like @3 + 3 don't look like they would be parsed as @(3 + 3), it looks like (@3) + 3.

So the syntax as @(expression) to make it clear where the expression ends. Then there's @identifier and @identifier(args) as shorthand for common cases that do look clear. I recently added @TemplateSingleArgument so you can do @"abc" or @3 as well. Perhaps the syntax can be expanded to allow @a.b.c(d) as well, as well as @a.b.c!d, though there's a risk of the rules getting convoluted.

July 28

Whenever there might be symbol clash, or when i want to make sure i can identify where something from from i do:

import me = my.awesome.module;


void main() {
    me.hi();
}