Re: How can overloads be distinguished on attributes alone?

2023-08-01 Thread Quirin Schroll via Digitalmars-d-learn

On Monday, 31 July 2023 at 18:15:25 UTC, Jonathan M Davis wrote:
On Monday, July 31, 2023 4:55:44 AM MDT Quirin Schroll via 
Digitalmars-d-learn wrote:

Apparently, functions can be overloaded solely distinguished by
attributes:
```d
void f(ref int x) pure { x = 1; }
void f(ref int x)  { x = 2; static int s; ++s; }
```

I thought that, maybe, a `pure` context calls the `pure` 
function and an impure context calls the impure function, but 
no: Calling `f` leads to an ambiguity error in both contexts. 
Even if that worked, what about inferred contexts, i.e. 
templates? In simple cases, they could forward the contexts in 
which they are called, but you can instantiate a template 
without calling it.


What am I missing here?


As things stand, the context in which a function is called is 
irrelevant. All that matters is the arguments.


And actually, allowing it would complicate any functions that 
infer attributes, potentially in a way that wouldn't work. For 
instance, if you have a templated function that's trying to 
infer purity, which one should it call? If it calls the pure 
one, it could be pure, but if it doesn't, it can't be. Either 
way, because the context isn't yet pure or not, the context 
can't be used to determine which should be called. Potentially, 
the compiler could just choose the pure function in that case, 
but the problem gets worse as you add more attributes.


I reasoned like this up about this point.

For instance, what happens when you have a function that's pure 
but not @safe and one that's @safe but not pure?

```d
void f() pure {...}
void f() @safe {...}
```
Should the compiler favor calling the pure one or the @safe 
one? And what if you then add something to the function that 
isn't @safe? If it was calling the @safe version before, should 
it switch to the pure one? And if the functions were @safe pure 
and @system and not pure instead

```d
void f() @safe pure {...}
void f() @system {...}
```
then changing the @safety or purity of some of the other code 
in the templated function could result in the loss of both 
attributes. And the more attributes are involved, the more 
complex the situation gets.


I didn’t even consider multiple attributes “in competition”.
At this point, it’s obvious that this can’t work.

In effect, we'd be making the attribute inference process have 
to go in two directions instead of just going from the bottom 
up, with the added complication that it would potentially need 
to choose between sets of attributes when choosing which 
function overload to call.


I tried assigning the address to a function pointer to 
disambiguate which overload I want. Didn’t work.


It's not necessarily the case that we couldn't sort all of this 
out and come up with a clean set of rules that allowed 
functions that infer their attributes to call the correct 
function, but it does get pretty complicated, and it comes with 
the serious downside that there's no guarantee that the 
overloads even do something similar to one another.


Actually, I do think it’s impossible to do the right thing. The 
spec can only make guesses on what a programmer might want.


And when you consider that it's pretty easy for a change in one 
part of the code to change which attributes are inferred in 
another part of the code, you could easily end up having a 
change in one part of your program resulting in drastically 
different behavior in a seemingly unrelated part of your 
program. And even worse, that change could be because of a 
library update, making it that much less obvious which parts of 
your program could suddenly change behavior due to a change in 
attributes.


Before looking into this, I thought that maybe this was in fact 
intended.


And I'm probably forgetting other issues that this would add to 
the mix. So, while it may very well be possible to do something 
along the lines of what you're looking for, I strongly suspect 
that it's simply not worth it.


You might have gotten me wrong. I don’t want to do something with 
it, I wondered if overloading based on attributes is a thing one 
has to consider when writing templates or something like that. A 
simple test was: Can I define those? If so, what happens on a 
function call? The spec doesn’t say anything about it.


As you say, overloads should essentially do the same. Overloads 
differing in attributes would differ in implementation details 
such that one can make guarantees and the other might give you 
better performance or other guarantees. Maybe that’s enough such 
that, if both implementations have value, they should differ in 
name (or  a kind of tag parameter for overload selection).


Filed as https://issues.dlang.org/show_bug.cgi?id=24063


Re: How can overloads be distinguished on attributes alone?

2023-07-31 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, July 31, 2023 4:55:44 AM MDT Quirin Schroll via Digitalmars-d-learn 
wrote:
> Apparently, functions can be overloaded solely distinguished by
> attributes:
> ```d
> void f(ref int x) pure { x = 1; }
> void f(ref int x)  { x = 2; static int s; ++s; }
> ```
>
> I thought that, maybe, a `pure` context calls the `pure` function
> and an impure context calls the impure function, but no: Calling
> `f` leads to an ambiguity error in both contexts. Even if that
> worked, what about inferred contexts, i.e. templates? In simple
> cases, they could forward the contexts in which they are called,
> but you can instantiate a template without calling it.
>
> What am I missing here?

As things stand, the context in which a function is called is irrelevant.
All that matters is the arguments.

And actually, allowing it would complicate any functions that infer
attributes, potentially in a way that wouldn't work. For instance, if you
have a templated function that's trying to infer purity, which one should it
call? If it calls the pure one, it could be pure, but if it doesn't, it
can't be. Either way, because the context isn't yet pure or not, the context
can't be used to determine which should be called. Potentially, the compiler
could just choose the pure function in that case, but the problem gets worse
as you add more attributes.

For instance, what happens when you have a function that's pure but not
@safe and one that's @safe but not pure?

void f() pure {...}
void f() @safe {...}

Should the compiler favor calling the pure one or the @safe one? And what if
you then add something to the function that isn't @safe? If it was calling
the @safe version before, should it switch to the pure one? And if the
functions were @safe pure and @system and not pure instead

void f() @safe pure {...}
void f() @system {...}

then changing the @safety or purity of some of the other code in the
templated function could result in the loss of both attributes. And the more
attributes are involved, the more complex the situation gets.

In effect, we'd be making the attribute inference process have to go in two
directions instead of just going from the bottom up, with the added
complication that it would potentially need to choose between sets of
attributes when choosing which function overload to call.

It's not necessarily the case that we couldn't sort all of this out and come
up with a clean set of rules that allowed functions that infer their
attributes to call the correct function, but it does get pretty complicated,
and it comes with the serious downside that there's no guarantee that the
overloads even do something similar to one another. And when you consider
that it's pretty easy for a change in one part of the code to change which
attributes are inferred in another part of the code, you could easily end up
having a change in one part of your program resulting in drastically
different behavior in a seemingly unrelated part of your program. And even
worse, that change could be because of a library update, making it that much
less obvious which parts of your program could suddenly change behavior due
to a change in attributes.

And I'm probably forgetting other issues that this would add to the mix. So,
while it may very well be possible to do something along the lines of what
you're looking for, I strongly suspect that it's simply not worth it.

- Jonathan M Davis





Re: How can overloads be distinguished on attributes alone?

2023-07-31 Thread bachmeier via Digitalmars-d-learn

On Monday, 31 July 2023 at 16:52:03 UTC, Dennis wrote:

On Monday, 31 July 2023 at 16:09:11 UTC, bachmeier wrote:
Is there a reason it would be difficult to make this not 
compile?


No, except that might result in code breakage.


The only way you could have code breakage is if you have

```
void f() { }
extern(C) void f() { }
```

but your program never calls f. The fix would be to comment out 
one of the duplicate function definitions.


Re: How can overloads be distinguished on attributes alone?

2023-07-31 Thread Dennis via Digitalmars-d-learn

On Monday, 31 July 2023 at 16:09:11 UTC, bachmeier wrote:
Is there a reason it would be difficult to make this not 
compile?


No, except that might result in code breakage.




Re: How can overloads be distinguished on attributes alone?

2023-07-31 Thread Dennis via Digitalmars-d-learn

On Monday, 31 July 2023 at 10:55:44 UTC, Quirin Schroll wrote:

What am I missing here?


The duplicate definition check doesn't consider whether a 
function is actually unambiguously callable (without e.g. traits 
getOverloads), it only prevents creating the same linker symbol 
multiple time. So you can even do this:


```D
  void f() { }
extern(C) void f() { }
```

But this straight up looks like a bug:
```D
   void g() { }
static void g() { } // static doesn't even do anything here
```



How can overloads be distinguished on attributes alone?

2023-07-31 Thread Quirin Schroll via Digitalmars-d-learn
Apparently, functions can be overloaded solely distinguished by 
attributes:

```d
void f(ref int x) pure { x = 1; }
void f(ref int x)  { x = 2; static int s; ++s; }
```

I thought that, maybe, a `pure` context calls the `pure` function 
and an impure context calls the impure function, but no: Calling 
`f` leads to an ambiguity error in both contexts. Even if that 
worked, what about inferred contexts, i.e. templates? In simple 
cases, they could forward the contexts in which they are called, 
but you can instantiate a template without calling it.


What am I missing here?


Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread ryuukk_ via Digitalmars-d-learn
Whenever there might be symbol clash, or when i want to make sure 
i can identify where something from from i do:


```d
import me = my.awesome.module;


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


Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread Dennis via Digitalmars-d-learn
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:

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

Being parsed as:

```D
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.




Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread Steven Schveighoffer via Digitalmars-d-learn

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


Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread Vijay Nayar via Digitalmars-d-learn
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?


Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread Steven Schveighoffer via Digitalmars-d-learn

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:

```D
@(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


Re: Syntax for Static Import of User Define Attributes

2023-07-28 Thread Vijay Nayar via Digitalmars-d-learn

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:

```D
@(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


Re: Syntax for Static Import of User Define Attributes

2023-07-27 Thread Dennis via Digitalmars-d-learn

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:

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


Re: Syntax for Static Import of User Define Attributes

2023-07-27 Thread Paul Backus via Digitalmars-d-learn

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;
}
```


Re: Inferred attributes errors in template function.

2022-05-27 Thread user1234 via Digitalmars-d-learn

On Friday, 27 May 2022 at 09:41:32 UTC, user1234 wrote:

[...]


on a side note that's funny how dmd manages to systematically 
print the less interesting message in both case.


They are actually correct, I dont know why at some point I 
thought there was a problem. For the float one it's oviously not 
pure and for the int one it's not safe...


OP wants better error message.



Re: Inferred attributes errors in template function.

2022-05-27 Thread Paul Backus via Digitalmars-d-learn

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

Is in dmd some flag that print errors similarly to this?:

```d
void main()@safe pure{
foo!long();
foo!float();
	//Error: `pure` function `D main` cannot call impure 
function `onlineapp.foo!float.foo`
	//Error: potentially `pure` function 
`onlineapp.foo!float.foo` cannot call impure function 
`onlineapp.bar!float.bar`
	//Error: potentially `pure` function 
`onlineapp.bar!float.bar` cannot access mutable static data `i`

```


No, there is nothing like this, at least not yet. It's being 
worked on, though.


https://github.com/dlang/dmd/pull/13957
https://github.com/dlang/dmd/pull/12383


Re: Inferred attributes errors in template function.

2022-05-27 Thread Tejas via Digitalmars-d-learn

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

Hello, I have this problem:

```d
static int i;

void bar(T)(){
static if(is(T == int))
(()@system => 1)();
static if(is(T == float))
i = 42;

}
void foo(T)(){
bar!T();
}

void main()@safe pure{
foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call 
impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call 
`@system` function `onlineapp.foo!int.foo`

}
```

When template function foo is called and its inferred 
attributes are not compatible with attributes of main, errors 
are not really useful. Compiler print that foo!float is not 
pure or foo!int is not @safe but doesn't tell why. Is in dmd 
some flag that print errors similarly to this?:


```d
void main()@safe pure{
foo!long();
foo!float();
	//Error: `pure` function `D main` cannot call impure 
function `onlineapp.foo!float.foo`
	//Error: potentially `pure` function 
`onlineapp.foo!float.foo` cannot call impure function 
`onlineapp.bar!float.bar`
	//Error: potentially `pure` function 
`onlineapp.bar!float.bar` cannot access mutable static data `i`

foo!int();  
	//Error: `@safe` function `D main` cannot call `@system` 
function `onlineapp.foo!int.foo`
	//Error: potentially `@safe` function 
`onlineapp.foo!int.foo` cannot call `@system` function 
`onlineapp.bar!int.bar`
 	//Error: potentially `@safe` function 
`onlineapp.bar!int.bar` cannot call `@system` delegate 
`onlineapp.bar!int.bar.__lambda1`

}
```


Use `-verrors=context` for dmd

```d
static int i;

void bar(T)(){
static if(is(T == int))
(()@system => 1)();
static if(is(T == float))
i = 42;

}
void foo(T)(){
bar!T();
}

void main()@safe pure{
foo!long();
	foo!float();	/+ onlineapp.d(16): Error: `pure` function `D main` 
cannot call impure function `onlineapp.foo!float.foo`

foo!float();
  ^ +/

	foo!int();		/+onlineapp.d(18): Error: `@safe` function `D main` 
cannot call `@system` function `onlineapp.foo!int.foo`

foo!int();  
^   +/
}
```


Re: Inferred attributes errors in template function.

2022-05-27 Thread user1234 via Digitalmars-d-learn

On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote:

Hello, I have this problem:

```d
static int i;

void bar(T)(){
static if(is(T == int))
(()@system => 1)();
static if(is(T == float))
i = 42;

}
void foo(T)(){
bar!T();
}

void main()@safe pure{
foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call 
impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call 
`@system` function `onlineapp.foo!int.foo`

}
```

[...]


on a side note that's funny how dmd manages to systematically 
print the less interesting message in both case.


Inferred attributes errors in template function.

2022-05-27 Thread vit via Digitalmars-d-learn

Hello, I have this problem:

```d
static int i;

void bar(T)(){
static if(is(T == int))
(()@system => 1)();
static if(is(T == float))
i = 42;

}
void foo(T)(){
bar!T();
}

void main()@safe pure{
foo!long();
	foo!float();	//Error: `pure` function `D main` cannot call 
impure function `onlineapp.foo!float.foo`
	foo!int();		//Error: `@safe` function `D main` cannot call 
`@system` function `onlineapp.foo!int.foo`

}
```

When template function foo is called and its inferred attributes 
are not compatible with attributes of main, errors are not really 
useful. Compiler print that foo!float is not pure or foo!int is 
not @safe but doesn't tell why. Is in dmd some flag that print 
errors similarly to this?:


```d
void main()@safe pure{
foo!long();
foo!float();
	//Error: `pure` function `D main` cannot call impure 
function `onlineapp.foo!float.foo`
	//Error: potentially `pure` function 
`onlineapp.foo!float.foo` cannot call impure function 
`onlineapp.bar!float.bar`
	//Error: potentially `pure` function 
`onlineapp.bar!float.bar` cannot access mutable static data `i`

foo!int();  
	//Error: `@safe` function `D main` cannot call `@system` 
function `onlineapp.foo!int.foo`
	//Error: potentially `@safe` function 
`onlineapp.foo!int.foo` cannot call `@system` function 
`onlineapp.bar!int.bar`
 	//Error: potentially `@safe` function 
`onlineapp.bar!int.bar` cannot call `@system` delegate 
`onlineapp.bar!int.bar.__lambda1`

}
```


Re: How are delegate attributes in fn signature inferred?

2022-05-23 Thread wjoe via Digitalmars-d-learn

On Monday, 23 May 2022 at 13:53:02 UTC, Adam D Ruppe wrote:

On Monday, 23 May 2022 at 13:44:53 UTC, wjoe wrote:

  [...]


You can actually make this work with `construct!(int[])` rather 
than plain `construct`. This is a (really annoying) deficiency 
in dmd's implementation. (that sdc solved btw proving it can be 
done just dmd never bothered)


[...]


I see. I figured the issue was an attribute mismatch.

Thanks for the explanation. Very much appreciated!


Re: How are delegate attributes in fn signature inferred?

2022-05-23 Thread Adam D Ruppe via Digitalmars-d-learn

On Monday, 23 May 2022 at 13:44:53 UTC, wjoe wrote:

  i.construct((ulong i) {return cast(int)(i+i);}).print;


You can actually make this work with `construct!(int[])` rather 
than plain `construct`. This is a (really annoying) deficiency in 
dmd's implementation. (that sdc solved btw proving it can be done 
just dmd never bothered)



Where's **pure nothrow @nogc @safe** coming from?


That's because it is a delegate literal, so it automatically 
figured out the tightest thing that works (this is also why it 
came as `function` instead of `delegate`, since it doesn't use 
any local variables from the enclosing function, it doesn't need 
the delegate pointer either).


But all those implicitly convert away so it doesn't really 
matter. The type system allows this, just the crappy 
implementation can't handle inferring that R when it is mentioned 
both as R r *and* ElementType!R - the stupid compiler sees 
ElementType!R and bails out.


Thus why you have to help it by telling the type when 
instantiating it


  i.construct!(int[])((ulong i) {return cast(int)(i+i);}).print;




How are delegate attributes in fn signature inferred?

2022-05-23 Thread wjoe via Digitalmars-d-learn

Hello,

Consider this example:
```d
module foo;

import std.stdio;
import std.algorithm;
import std.traits;
import std.range;

void print(R)(R r) {
  static assert(isIterable!R);
  r.each!writeln;
}

auto construct(R)(R r, ElementType!R delegate(ulong i) fn) {
  static assert(isIterable!R && hasAssignableElements!R);
  ulong i = 1;
  r.each!((ref e) => e = fn(i));
  return r;
}

unittest {
  int[] i; i.length = 4;
  i.construct((ulong i) {return cast(int)(i+i);}).print;
}
```

```shell

dmd -unittest -main foo.d


Error: template 'foo.construct' cannot deduce function from 
argument types '!()(int[], int function(ulong i) pure nothrow 
@nogc @safe)', candidates are: 'construct(R)(R r, ElementType!R 
delegate(ulong i) fn)'

```

Where's **pure nothrow @nogc @safe** coming from?
Also, why is *(ulong i) {return cast(int)(i+i);}* passed as a 
function?
The error message for passing a delegate is the same except with 
*function* substituted for *delegate*.


Re: Attributes (lexical)

2021-11-25 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Thursday, 25 November 2021 at 12:16:50 UTC, rumbu wrote:
I try to base my reasoning on specification, dmd is not always 
a good source of information, the lexer is polluted by old 
features or right now by the ImportC feature, trying to lex D 
an C in the same time.


Alright. I haven't looked at it after the ```importC``` feature 
was started on.


(The lexer code takes a bit of browsing to get used to, but it 
isn't all that challenging once you are into it.)




Re: Attributes (lexical)

2021-11-25 Thread Dennis via Digitalmars-d-learn

On Thursday, 25 November 2021 at 12:09:55 UTC, Dennis wrote:

This should also be fixed in the spec.


Filed as:

Issue 22543 - [spec] grammar blocks use unspecified notation:
https://issues.dlang.org/show_bug.cgi?id=22543

Issue 22544 - [spec] C++ and Objective-C are not single tokens
https://issues.dlang.org/show_bug.cgi?id=22544



Re: Attributes (lexical)

2021-11-25 Thread rumbu via Digitalmars-d-learn
On Thursday, 25 November 2021 at 11:25:49 UTC, Ola Fosheim 
Grøstad wrote:

On Thursday, 25 November 2021 at 10:41:05 UTC, Rumbu wrote:
I am not asking this questions out of thin air, I am trying to 
write a conforming lexer and this is one of the ambiguities.


I think it is easier to just look at the lexer in the dmd 
source. The D language does not really have a proper spec, it 
is more like an effort to document the implementation.


I try to base my reasoning on specification, dmd is not always a 
good source of information, the lexer is polluted by old features 
or right now by the ImportC feature, trying to lex D an C in the 
same time.


DMD skips the new line if the file was not specified, that's why 
the "filename" is unexpected on a new line:

https://github.com/dlang/dmd/blob/d374003a572fe0c64da4aa4dcc55d894c648514b/src/dmd/lexer.d#L2838

libdparse completely ignores the contents after #line skipping 
everything until EOL, even a EOF/NUL marker which should end the 
lexing:

https://github.com/dlang-community/libdparse/blob/7112880dae3f25553d96dae53a445c16261de7f9/src/dparse/lexer.d#L1100



Re: Attributes (lexical)

2021-11-25 Thread zjh via Digitalmars-d-learn

On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote:


#

//this works

line


I hate `#`.


Re: Attributes (lexical)

2021-11-25 Thread Dennis via Digitalmars-d-learn

On Thursday, 25 November 2021 at 10:41:05 UTC, Rumbu wrote:

Well:

```
#line IntegerLiteral Filespec? EndOfLine
```

Having EndOfLine at the end means for me that there are no 
other EOLs between, otherwise this syntax should pass but it's 
not (DMD last):


```d
#line 12
"source.d"
```


The lexical grammar section starts with:

The source text is decoded from its source representation into 
Unicode Characters. The Characters are further divided into: 
WhiteSpace, EndOfLine, Comments, SpecialTokenSequences, and 
Tokens, with the source terminated by an EndOfFile.


What it's failing to mention is how in the lexical grammar rules, 
spaces denote 'immediate concatenation' of the characters/rules 
before and after it, e.g.:

```
DecimalDigits:
DecimalDigit
DecimalDigit DecimalDigits
```
`3 1  4` is not a single `IntegerLiteral`, it needs to be `314`.

Now in the parsing grammar, it should mention that spaces denote 
immediate concatenation of *Tokens*, with arbitrary *Comments* 
and *WhiteSpace* inbetween. So the rule:

```
AtAttribute:
@ nogc
```
Means: an @ token, followed by arbitrary comments and whitespace, 
followed by an identifier token that equals "nogc". That explains 
your first example.


Regarding this lexical rule:
```
#line IntegerLiteral Filespec? EndOfLine
```
This is wrong already from a lexical standpoint, it would suggest 
a SpecialTokenSequence looks like this:

```
#line10"file"
```

The implementation actually looks for a # token, skips 
*WhiteSpace* and *Comment*s, looks for an identifier token 
("line"), and then it goes into a custom loop that allows 
separation by *WhiteSpace* but not *Comment*, and also the first 
'\n' will be assumed to be the final *EndOfLine*, which is why 
this fails:

```
#line 12
"source.d"
```
It thinks it's done after "12".

In conclusion the specification should:
- define the notation used in lexical / parsing grammar blocks
- clearly distinguish lexical / parsing blocks
- fix up the `SpecialTokenSequence` definition (and maybe change 
dmd as well)


By the way, the parsing grammar defines:
```
LinkageType:
C
C++
D
Windows
System
Objective-C
```
C++ and Objective-C cannot be single tokens currently, so they 
are actually 2/3, which is why these are allowed:


```D
extern(C
   ++)
void f() {}

extern(Objective
   -
   C)
void g() {}
```
This should also be fixed in the spec.

I am not asking this questions out of thin air, I am trying to 
write a conforming lexer and this is one of the ambiguities.


That's cool! Are you writing an editor plugin?



Re: Attributes (lexical)

2021-11-25 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Thursday, 25 November 2021 at 10:41:05 UTC, Rumbu wrote:
I am not asking this questions out of thin air, I am trying to 
write a conforming lexer and this is one of the ambiguities.


I think it is easier to just look at the lexer in the dmd source. 
The D language does not really have a proper spec, it is more 
like an effort to document the implementation.




Re: Attributes (lexical)

2021-11-25 Thread Rumbu via Digitalmars-d-learn

On Thursday, 25 November 2021 at 10:10:25 UTC, Dennis wrote:

On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote:
Also, this works also for #line, even if the specification 
tells us that all tokens must be on the same line


Where does it say that?


Well:

```
#line IntegerLiteral Filespec? EndOfLine
```

Having EndOfLine at the end means for me that there are no other 
EOLs between, otherwise this syntax should pass but it's not (DMD 
last):


```d
#line 12
"source.d"
```

I am not asking this questions out of thin air, I am trying to 
write a conforming lexer and this is one of the ambiguities.




Re: Attributes (lexical)

2021-11-25 Thread Dennis via Digitalmars-d-learn

On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote:
Also, this works also for #line, even if the specification 
tells us that all tokens must be on the same line


Where does it say that?



Re: Attributes (lexical)

2021-11-25 Thread Elronnd via Digitalmars-d-learn

On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote:

Is that ok or it's a lexer bug?


@ (12) does exactly what I would expect.  @nogc I always assumed 
was a single token, but the spec says otherwise.  I suppose that 
makes sense.


#line is dicier as it is not part of the grammar proper; however 
the spec describes it as a 'special token sequence', and comments 
are not tokens, so I think the current behaviour is correct.


Re: Attributes (lexical)

2021-11-25 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Thursday, 25 November 2021 at 08:06:27 UTC, rumbu wrote:

Is that ok or it's a lexer bug?


Yes. The lexer just eats whitespace and the parser accepts way 
too much.




Attributes (lexical)

2021-11-25 Thread rumbu via Digitalmars-d-learn

Just playing around with attributes.

This is valid D code:

```d

@


nogc: //yes, this is @nogc in fact, even some lines are between


@

/* i can put some comments
*/

/** even some documentation
*/

// single line comments also

(12)

// yes, comments and newlines are allowed between attribute and 
declaration



int x; //@(12) is attached to declaration
```

Is that ok or it's a lexer bug?


Also, this works also for #line, even if the specification tells 
us that all tokens must be on the same line



```d

#

//this works

line

/* this too */

12

//this is #line 12


```


Re: How do I assign attributes of a function to another function?

2021-11-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 5 November 2021 at 06:19:16 UTC, Li30U wrote:

...e.g.
```d
// ...
mixin ("ReturnType /*...snip...*/ " ~ member ~ "()(Parameters! 
/*...snip...*/

```

Note the `()` before parameter list. This would make your member 
function a function template, for which attributes will be 
inferred by the compiler based on the calls you make in the 
function body.


Of course, making it a template like this makes it non-composable 
with that same type as you're only inspecting functions, so you 
wouldn't be able to do e.g. a Group!(Group!(A, 3), 4);


Re: How do I assign attributes of a function to another function?

2021-11-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Friday, 5 November 2021 at 06:19:16 UTC, Li30U wrote:
I am creating a templated object that is a storehouse for a 
heap object and executes their methods and returns an array of 
results. With the help of a template, I want to achieve this, 
but I want to assign the same attributes to the function. How 
can one pass the attributes of a function to another function?


There's https://dlang.org/spec/traits.html#getFunctionAttributes 
. Or you could define your functions as function templates, 
letting the compiler infer attributes. Especially as it looks 
like you function's attributes may not be made the same as the 
ones you defer to: since you're allocating with the GC, your 
function cannot be @nogc even if a deferred one can.


How do I assign attributes of a function to another function?

2021-11-05 Thread Li30U via Digitalmars-d-learn
I am creating a templated object that is a storehouse for a heap 
object and executes their methods and returns an array of 
results. With the help of a template, I want to achieve this, but 
I want to assign the same attributes to the function. How can one 
pass the attributes of a function to another function?


```d
template Group(T, int objects)
{
struct Group
{
enum __length = __traits(allMembers, T).length;

T[objects] __objects;

this(T[objects] __objctor) @safe
{
__objects = __objctor;
}

static foreach (member; __traits(allMembers, T))
{
static if ( __traits(getVisibility, 
__traits(getMember, T, member)) != "private" &&
__traits(getVisibility, 
__traits(getMember, T, member)) != "protected")

{
static if (isFunction!(__traits(getMember, T, 
member)))

{
mixin ("ReturnType!(__traits(getMember, T, 
member))[] " ~ member ~ "(Parameters!(__traits(getMember, T, 
member)) args)

{
ReturnType!(__traits(getMember, T, 
member))[] results;

foreach (e; __objects)
results ~= e." ~ member ~ "(args);

return results;
}");
}else
static if (member != "Monitor")
{
mixin ("typeof(__traits(getMember, T, 
member))[] " ~ member ~ "()

{
typeof(__traits(getMember, T, member))[] 
results;

foreach (e; __objects)
results ~= e." ~ member ~ ";
return results;
}");
}
}
}
}
}
```


Re: interface function member declarations needing parameter attributes ?

2021-07-18 Thread someone via Digitalmars-d-learn

On Sunday, 18 July 2021 at 11:03:24 UTC, Adam D Ruppe wrote:

Fun fact there: any child implementations do NOT need to 
specify the attribute there; the compiler will copy it from the 
interface for you.


I suppose these are the day-to-day minor details you can rely on 
to avoid typing a lot of things, but, in the end, I prefer to 
state things clearly because in the event someone need to port my 
code I'll be making his life miserable trying to understand all 
these defaults; and I am not talking explicitly D here, I am 
talking any language, I did never forget a project in which I was 
involved porting a big development from C++ ... it took almost 3X 
the time we all think back then it needed to. From that time on I 
try to avoid fancy things with code whenever possible -just 
common sense.


Re: interface function member declarations needing parameter attributes ?

2021-07-18 Thread Adam D Ruppe via Digitalmars-d-learn

On Sunday, 18 July 2021 at 03:27:04 UTC, someone wrote:
I have an interface with function members *not* being declared 
@safe (at first glance it seemed irrelevant to me just to mark 
@safe a declaration and not an actual implementation).


Yeah, that'd be promising all child implementations are @safe.

Fun fact there: any child implementations do NOT need to specify 
the attribute there; the compiler will copy it from the interface 
for you.


interface I {
   @safe void foo();
}

class C : I {
   void foo(); // automatically copies @safe from interface
}


If you leave it off, you are not promising safe, but children are 
still allowed to use it anyway. The general rule is child classes 
can be stricter than the parent if they want to be, but they 
don't have to be.



interface I {
   void foo(); // not safe
}

class C : I {
void foo(); // OK, not safe, interface didn't force it
}

class C2 : I {
@safe void foo(); // OK, class can be stricter than parent. 
now safe if used through C2, but the interface can't promise it 
is C2 instead of C, so it still follows @system rules.

}

class C3 : C2 {
override void foo(); // automatically @safe since it picks it 
up from parent C2

}


Re: interface function member declarations needing parameter attributes ?

2021-07-17 Thread someone via Digitalmars-d-learn

On Saturday, 17 July 2021 at 21:01:00 UTC, Adam Ruppe wrote:

From the interface perspective: are these signatures identical 
or not ?


No, they are very different.


This helped me solve an issue that I carried since a few days ago:

I have an interface with function members *not* being declared 
@safe (at first glance it seemed irrelevant to me just to mark 
@safe a declaration and not an actual implementation).


I also have former @safe member functions in classes implementing 
this interface that at some point I did have to take out the 
@safe declarations because the compiler didn't like them anymore 
due to some change I made which I didn't link to them, and from 
the on I did not quite understand why it was complaining since 
everything seemed perfect to me (as usual ha).


Now that I marked the ones in the interface @safe I can also mark 
the ones implementing them @safe again and now everything is 
@safe and working properly.


Another day, another lesson learned.


Re: interface function member declarations needing parameter attributes ?

2021-07-17 Thread someone via Digitalmars-d-learn

On Saturday, 17 July 2021 at 22:48:00 UTC, Adam D Ruppe wrote:

On Saturday, 17 July 2021 at 22:43:15 UTC, someone wrote:
So the lesson learned is that interfaces can also mandate 
member function's parameter attributes then ... right ?


A subclass must accept anything the parent class can, but it 
can also make it stricter if you want.


class Base {
void foo(Object o) {}
}

class Derived : Base {
override void foo(const Object o) {}
}


That's legal because const also accepts mutable. Derived is 
stricter than Base which is permitted. But the other way around:


class Base {
void foo(const Object o) {}
}

class Derived : Base {
override void foo(Object o) {}
}

is NOT allowed because the mutable thing in derived cannot be 
passed back to the base interface implicitly.


Perfectly clear; thanks Adam :) !



Re: interface function member declarations needing parameter attributes ?

2021-07-17 Thread Adam D Ruppe via Digitalmars-d-learn

On Saturday, 17 July 2021 at 22:43:15 UTC, someone wrote:
So the lesson learned is that interfaces can also mandate 
member function's parameter attributes then ... right ?


A subclass must accept anything the parent class can, but it can 
also make it stricter if you want.


class Base {
void foo(Object o) {}
}

class Derived : Base {
override void foo(const Object o) {}
}


That's legal because const also accepts mutable. Derived is 
stricter than Base which is permitted. But the other way around:


class Base {
void foo(const Object o) {}
}

class Derived : Base {
override void foo(Object o) {}
}

is NOT allowed because the mutable thing in derived cannot be 
passed back to the base interface implicitly.




Re: interface function member declarations needing parameter attributes ?

2021-07-17 Thread someone via Digitalmars-d-learn

On Saturday, 17 July 2021 at 21:01:00 UTC, Adam Ruppe wrote:


No, they are very different.


So the lesson learned is that interfaces can also mandate member 
function's parameter attributes then ... right ?


But you also don't gain much from const here and that ref is 
probably actively harmful so i wouldn't use them here.


ref is gone.




Re: interface function member declarations needing parameter attributes ?

2021-07-17 Thread Adam Ruppe via Digitalmars-d-learn

On Saturday, 17 July 2021 at 20:42:06 UTC, someone wrote:
From the interface perspective: are these signatures identical 
or not ?


No, they are very different.

But you also don't gain much from const here and that ref is 
probably actively harmful so i wouldn't use them here.


interface function member declarations needing parameter attributes ?

2021-07-17 Thread someone via Digitalmars-d-learn

```d
public interface intefaceWhatever {

   public bool doSomething(
  dstring lstrID,
  classX robjX
  );

}
```

vs

```d
public interface intefaceWhatever {

   public bool doSomething(
  const dstring lstrID,
  ref classX robjX
  );

}
```

From the interface perspective: are these signatures identical or 
not ?


Is the latter needed ... or if not, makes sense as best practice ?


Re: Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:36:09 UTC, Adam D. Ruppe wrote:

On Friday, 4 June 2021 at 11:33:32 UTC, wjoe wrote:
This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so 
I could use them in @nogc territory by just switching out the 
allocator.


If they are templates, just don't specify attributes and the 
compiler will infer them for you.


If they are not templates, you have to do a separate copy under 
version or static if.


That's good to know. Thanks :)
A separate copy is exactly what I wanted to avoid but since they 
are templates it's np.




Re: Is it possible to set function attributes conditionally?

2021-06-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:33:32 UTC, wjoe wrote:
This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so I 
could use them in @nogc territory by just switching out the 
allocator.


If they are templates, just don't specify attributes and the 
compiler will infer them for you.


If they are not templates, you have to do a separate copy under 
version or static if.


Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

Hi,

Consider Allocators, e.g.:

```d
struct Mallocator
{
   enum usesGC = false;

   /// implement alloc, free, etc. @nogc
}

struct GCAllocator
{
  enum usesGC = true;

   /// implement alloc, free, etc. via the GC
}
```

Now I want to have the function attributes set depending on the 
allocator implementation


```d
template AutoGC(ALLOCATOR) if (isAllocator!ALLOCATOR)
{
   static if (!ALLOCATOR.usesGC)
  AutoGC = pragma(attrib, @nogc);
   else
  AutoGC = pragma(attrib, none);
}

@AutoGC!ALLOCATOR void fun(ALLOCATOR)() if(isAllocator!ALLOCATOR)
{
   void* p = ALLOCATOR.alloc(1024);
   // do something with p
   ALLOCATOR.free(p);
}
```

So fun!Mallocator would be @nogc and fun!GCAllocator wouldn't be 
@nogc.


This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so I 
could use them in @nogc territory by just switching out the 
allocator.


Is it possible to do something like this ?



Re: opApply and attributes

2020-07-16 Thread solidstate1991 via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 00:17:14 UTC, solidstate1991 wrote:

Something like that, but with @safe, pure, etc. attributes.


I've tried to "bruteforce" it by generating functions with 
combinations of attributes, and it kinda works, but is a very 
janky solution.


I'll brainstorm some DIP to fix this issue.


Re: opApply and attributes

2020-07-13 Thread solidstate1991 via Digitalmars-d-learn

On Tuesday, 7 July 2020 at 20:53:05 UTC, Ali Çehreli wrote:
I am not sure whether I understand it correctly but there has 
been a request for opApply() to gain the attributes of the 
delegate (or the range?). In other words, "transfer the 
attributes to opApply". This is needed because I want opApply() 
to work with any foreach body, attributes of which opApply() 
cannot know.


I am sure I created an issue on Dlang bug tracker for Weka on 
this topic but I can't find it now. (Aside: The search boxes on 
the bug tracker are inferior to the automatic search feature 
that works when creating a bug.) Anyway, this one seems related:


  https://issues.dlang.org/show_bug.cgi?id=7543

Ali


Something like that, but with @safe, pure, etc. attributes.


Re: opApply and attributes

2020-07-07 Thread Ali Çehreli via Digitalmars-d-learn
On 7/6/20 5:20 PM, solidstate1991 wrote:> See implementation of data 
structure here:
> 
https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L565 


>
>
> If I try to compile this code, it'll fail, limiting it's usecase:
>
> @safe pure unittest {
>  alias IntMap = TreeMap!(int, int, false);
>  IntMap test;
>  test[5] = 5;
>  test[7] = 7;
>  test[3] = 3;
>  foreach(elem, key; test) {
>  assert(elem == key);
>  }
> }

I am not sure whether I understand it correctly but there has been a 
request for opApply() to gain the attributes of the delegate (or the 
range?). In other words, "transfer the attributes to opApply". This is 
needed because I want opApply() to work with any foreach body, 
attributes of which opApply() cannot know.


I am sure I created an issue on Dlang bug tracker for Weka on this topic 
but I can't find it now. (Aside: The search boxes on the bug tracker are 
inferior to the automatic search feature that works when creating a 
bug.) Anyway, this one seems related:


  https://issues.dlang.org/show_bug.cgi?id=7543

Ali



Re: opApply and attributes

2020-07-07 Thread solidstate1991 via Digitalmars-d-learn

On Tuesday, 7 July 2020 at 13:33:41 UTC, Paul Backus wrote:


You can make opApply a template:

int opApply(Dg)(Dg dg)
if (is(Dg : scope int delegate(ref E)))
{
// etc.
}

Because `scope int delegate(ref E) @safe` implicitly converts 
to `scope int delegate(ref E)`, this version will accept both 
@safe and non-@safe delegates. (And likewise for the other 
function attributes.)


Unfortunately this doesn't really work, even with explicitly 
defined foreach arguments.


Re: opApply and attributes

2020-07-07 Thread Stanislav Blinov via Digitalmars-d-learn

On Tuesday, 7 July 2020 at 13:33:41 UTC, Paul Backus wrote:


You can make opApply a template:

int opApply(Dg)(Dg dg)
if (is(Dg : scope int delegate(ref E)))
{
// etc.
}

Because `scope int delegate(ref E) @safe` implicitly converts 
to `scope int delegate(ref E)`, this version will accept both 
@safe and non-@safe delegates. (And likewise for the other 
function attributes.)


Yeah, but unfortunately then this won't work:


foreach(elem; test) {
assert(elem == key);
}


you'd have to spell out the types for `elem`.


Re: opApply and attributes

2020-07-07 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 7 July 2020 at 00:20:40 UTC, solidstate1991 wrote:
See implementation of data structure here: 
https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L565


If I try to compile this code, it'll fail, limiting it's 
usecase:


@safe pure unittest {
alias IntMap = TreeMap!(int, int, false);
IntMap test;
test[5] = 5;
test[7] = 7;
test[3] = 3;
foreach(elem, key; test) {
assert(elem == key);
}
}


You can make opApply a template:

int opApply(Dg)(Dg dg)
if (is(Dg : scope int delegate(ref E)))
{
// etc.
}

Because `scope int delegate(ref E) @safe` implicitly converts to 
`scope int delegate(ref E)`, this version will accept both @safe 
and non-@safe delegates. (And likewise for the other function 
attributes.)


opApply and attributes

2020-07-06 Thread solidstate1991 via Digitalmars-d-learn
See implementation of data structure here: 
https://github.com/ZILtoid1991/collections-d/blob/master/source/collections/treemap.d#L565


If I try to compile this code, it'll fail, limiting it's usecase:

@safe pure unittest {
alias IntMap = TreeMap!(int, int, false);
IntMap test;
test[5] = 5;
test[7] = 7;
test[3] = 3;
foreach(elem, key; test) {
assert(elem == key);
}
}

I know that implementing foreach with other means do exist, and I 
used them in my other data structures, but it's much more 
difficult (and potentially slower) to implement that within a 
binary search tree.


Should I change the `opApply` into the `popfront` - `front` - 
`empty` trinity, or write a template that overrides all the 
potential attribute combinations?


Maybe D needs a template for attributes somehow, or something 
like that.


Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-13 Thread Jacob Carlborg via Digitalmars-d-learn

On 2020-05-12 06:02, Steven Schveighoffer wrote:

If you want a list of ALL symbols that have the UDA in the application, 
that would require some form of runtime reflection (like Java). D has 
very limited support for runtime reflection. In D, you would use some 
form of registration to tell the system about your symbols.


I think it's possible to implement the `RTInfo` template in `object.d`. 
But that requires a custom druntime.


`RTInfo` is a template that is instantiated once for each type in the 
program.


--
/Jacob Carlborg


Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-12 Thread Doug via Digitalmars-d-learn
On Tuesday, 12 May 2020 at 04:02:18 UTC, Steven Schveighoffer 
wrote:


In the case of serialization/deserialization, you give an 
instance of a type to serialize or deserialize. Then the 
library can search the symbols inside that type to see if any 
has the UDA you are looking for.


In the Rust example, there is a line of code:

let p: Person = serde_json::from_str(data)?;

I'm assuming that this conversion is detected and figured out 
(i.e. this is how serde "finds" the type desired). For D, it 
would look something like:


auto p = serde_json.from_str!Person(data);

If you want a list of ALL symbols that have the UDA in the 
application, that would require some form of runtime reflection 
(like Java). D has very limited support for runtime reflection. 
In D, you would use some form of registration to tell the 
system about your symbols.


-Steve


Thanks for the feedback.
I've got a better idea of what is and isn't possible now.

I'll see about looking at one or two D JSON libraries to see how 
they approach things. It should help shed some more light on the 
subject.






Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/11/20 11:30 PM, Doug wrote:

On Tuesday, 12 May 2020 at 02:53:53 UTC, Adam D. Ruppe wrote:


see std.traits.getSymbolsByUDA


Thanks for the link. I did see that one. But that function searches 
within known symbols. My use case if for a library that's used outside 
of my application. In that case, I wouldn't know which symbol a library 
applies an annotation to. This is why I asked for how to get a list of 
unknown symbols from a known UDA.


To use a REST frame work as an example, I would supply a @GET annotation 
and a user would apply that annotation to a handler method. I wouldn't 
know the method or module in advanced so I wouldn't know which symbol to 
pass to "getSymbolsByUDA" of any of it's sibling functions.


I'm curious to see what I'd be able to do if this is possible.


So the idea is that you know the parent symbol.

In the case of serialization/deserialization, you give an instance of a 
type to serialize or deserialize. Then the library can search the 
symbols inside that type to see if any has the UDA you are looking for.


In the Rust example, there is a line of code:

let p: Person = serde_json::from_str(data)?;

I'm assuming that this conversion is detected and figured out (i.e. this 
is how serde "finds" the type desired). For D, it would look something like:


auto p = serde_json.from_str!Person(data);

If you want a list of ALL symbols that have the UDA in the application, 
that would require some form of runtime reflection (like Java). D has 
very limited support for runtime reflection. In D, you would use some 
form of registration to tell the system about your symbols.


-Steve


Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-11 Thread Doug via Digitalmars-d-learn

On Tuesday, 12 May 2020 at 02:53:53 UTC, Adam D. Ruppe wrote:


see std.traits.getSymbolsByUDA


Thanks for the link. I did see that one. But that function 
searches within known symbols. My use case if for a library 
that's used outside of my application. In that case, I wouldn't 
know which symbol a library applies an annotation to. This is why 
I asked for how to get a list of unknown symbols from a known UDA.


To use a REST frame work as an example, I would supply a @GET 
annotation and a user would apply that annotation to a handler 
method. I wouldn't know the method or module in advanced so I 
wouldn't know which symbol to pass to "getSymbolsByUDA" of any of 
it's sibling functions.


I'm curious to see what I'd be able to do if this is possible.


Re: Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-11 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 12 May 2020 at 02:51:39 UTC, Doug wrote:
So far I've only seen a way to get unknown UDAs from known 
symbols but not how to get unknown symbols from UDAs. Is there 
any documentation for how to get a list of symbols annotated 
with a specific UDA?


see std.traits.getSymbolsByUDA

http://dpldocs.info/experimental-docs/std.traits.getSymbolsByUDA.html

there's some caveats, like it only searches one particular parent 
symbol for its children


(that's because the way this works is you reflect through 
children checking each symbol child's uda list to see if it is 
present)


but it basically works for many things at least contained 
per-module. you can pass each module you care about in though to 
generate a more full list


Get unknown symbol (struct, method, class) tagged with User Defined Attributes

2020-05-11 Thread Doug via Digitalmars-d-learn
I've seen a lot of examples of how to get a list of User Defined 
Attributes from a known symbol but I haven't seen any for how to 
get a list of symbols when only the UDA is known.


The use case is the same as seen in Rust with Serde[1]. Library 
users annotate a struct to mark it for serialization. In Java and 
Spring, you can mark a method with @Secured to add authorization 
to an endpoint[2]. In both of these cases, you have no idea which 
symbol the UDA will be applied to.


So far I've only seen a way to get unknown UDAs from known 
symbols but not how to get unknown symbols from UDAs. Is there 
any documentation for how to get a list of symbols annotated with 
a specific UDA?



1: Serde: https://github.com/serde-rs/json
2: Spring: 
https://www.baeldung.com/spring-security-method-security




Re: Extracting user defined attributes on function parameters

2020-04-18 Thread Simen Kjærås via Digitalmars-d-learn

On Saturday, 18 April 2020 at 09:19:48 UTC, Simen Kjærås wrote:
On Wednesday, Friday, 17 Apr 2020 17:45:47 UTC, H. S. Teoh 
wrote:


I wonder if the ultimate cause of the above case is ultimately 
caused by
the change to import semantics that hid private symbols from 
outside the
module. Perhaps something, somewhere, is triggering an illegal 
access of
a private symbol, which percolates up the call/instantiation 
stack and

causing what appears to be a strange compiler discrepancy.


Not unlikely. Importing the module defining S in the module 
defining ParameterDefaults does indeed make things compile. 
Hiding S by making it private makes the error return.


It's not about private. Or even if it is, there's other issues. 
Proof:


struct A {
struct S {}
void f(@S int = 3);
pragma(msg, Issue20744!f);
}

template Issue20744(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
alias Issue20744 = (PT args) {};
}
}

--
  Simen


Re: Extracting user defined attributes on function parameters

2020-04-18 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, Friday, 17 Apr 2020 17:45:47 UTC, H. S. Teoh wrote:

I wonder if the ultimate cause of the above case is ultimately 
caused by
the change to import semantics that hid private symbols from 
outside the
module. Perhaps something, somewhere, is triggering an illegal 
access of
a private symbol, which percolates up the call/instantiation 
stack and

causing what appears to be a strange compiler discrepancy.


Not unlikely. Importing the module defining S in the module 
defining ParameterDefaults does indeed make things compile. 
Hiding S by making it private makes the error return.


(for whatever reason your message isn't visible in the web 
interface)


--
  Simen


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 17 April 2020 at 18:05:39 UTC, Jean-Louis Leroy wrote:
Interesting example, but all hope is not lost. `a` could 
(should?) be passed as an alias in __parameters.


Well, __parameters itself actually kinda works. The compiler 
knows it is an expression and can stringify it or evaluate it on 
demand for you...


but how to express that in D code is pretty weird and idk how to 
library that. Using in-site for various things can be done but 
putting it in a lib is idk.


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Friday, 17 April 2020 at 18:05:39 UTC, Jean-Louis Leroy wrote:

Interesting example, but all hope is not lost. `a` could 
(should?) be passed as an alias in __parameters.


Okay I take this back...



Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Friday, 17 April 2020 at 17:48:06 UTC, Adam D. Ruppe wrote:
On Friday, 17 April 2020 at 17:31:32 UTC, Jean-Louis Leroy 
wrote:
Well, can't do. I need this purely at compile time, and 
cross-module.


And the CTFE engine gets weird with it too dmd will have to 
fix this.


But default parameters might not be possible in general at CT 
anyway... it is actually possible to define it to a variable. 
Observe:


int a;

void f(int arg = a) { // default arg is to use the global...
import std.stdio; writeln(arg);
}

void main() {
f(); // 0 this time
a = 4; // and it can be changed at runtime!
f(); // will now say 4
}


Interesting example, but all hope is not lost. `a` could 
(should?) be passed as an alias in __parameters.





Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 17 April 2020 at 17:31:32 UTC, Jean-Louis Leroy wrote:
Well, can't do. I need this purely at compile time, and 
cross-module.


And the CTFE engine gets weird with it too dmd will have to 
fix this.


But default parameters might not be possible in general at CT 
anyway... it is actually possible to define it to a variable. 
Observe:


int a;

void f(int arg = a) { // default arg is to use the global...
import std.stdio; writeln(arg);
}

void main() {
f(); // 0 this time
a = 4; // and it can be changed at runtime!
f(); // will now say 4
}



Re: Extracting user defined attributes on function parameters

2020-04-17 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Apr 17, 2020 at 05:33:23PM +, Simen Kjærås via Digitalmars-d-learn 
wrote:
> On Friday, 17 April 2020 at 16:54:42 UTC, Adam D. Ruppe wrote:
[...]
> > So pragma(msg) is doing something really weird, the bug doesn't
> > appear to be in Phobos per se, I think it is the compiler doing the
> > wrong thing, it seems to me it works inside a function scope but not
> > at module scope..
> 
> It's even more fascinating - the issue doesn't occur if
> ParameterDefaults is defined in the same module that it's used in, and
> it works if there's a type with the same name as the UDA. Reducing the
> code as much as I can, I get this:
[...]
> The above code works, and prints "3". If you move ParameterDefaults to
> a different module, something like this:
[...]
> Then you get an error message about 'undefined identifier S'. Add some
> kind of S to bar, and you get an error message about S not being
> readable at compile-time or things just work if it is readable. It
> seems the UDA is being looked up in the wrong context.

This is reminiscient of a bug I found recently, the ultimate cause of
which is accessing a private symbol across modules, which is verboten,
but it manifested itself in a way that appeared completely unrelated --
it turned an attribute-inferred function into @system where one expected
@safe, which percolated up the call stack and ended up as a template
mismatch error, which then shunted the template resolution into another
overload which finally generated a totally unrelated compile error (very
unhelpful!).

I wonder if the ultimate cause of the above case is ultimately caused by
the change to import semantics that hid private symbols from outside the
module. Perhaps something, somewhere, is triggering an illegal access of
a private symbol, which percolates up the call/instantiation stack and
causing what appears to be a strange compiler discrepancy.

Or perhaps it's a compiler bug. :-D


T

-- 
It is of the new things that men tire --- of fashions and proposals and 
improvements and change. It is the old things that startle and intoxicate. It 
is the old things that are young. -- G.K. Chesterton


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Friday, 17 April 2020 at 16:54:42 UTC, Adam D. Ruppe wrote:

void main() {
import std.stdio;
writeln(ParameterDefaults!f.stringof);
}

and it is fine.


Well, can't do. I need this purely at compile time, and 
cross-module. That's for supporting UDAs and default parameter 
values in openmethods. If you want a peek at what I am up to, see 
here: 
https://github.com/jll63/openmethods.d/blob/bolts-reflection/source/bolts/reflection/metafunction.d


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 17 April 2020 at 16:54:42 UTC, Adam D. Ruppe wrote:

This part seems fine...


pragma(msg, ParameterDefaults!f.stringof);


It is this, specifically, that causes the problem. Replace it 
with:


void main() {
import std.stdio;
writeln(ParameterDefaults!f.stringof);
}

and it is fine.

So pragma(msg) is doing something really weird, the bug doesn't 
appear to be in Phobos per se, I think it is the compiler doing 
the wrong thing, it seems to me it works inside a function 
scope but not at module scope..


It's even more fascinating - the issue doesn't occur if 
ParameterDefaults is defined in the same module that it's used 
in, and it works if there's a type with the same name as the UDA. 
Reducing the code as much as I can, I get this:


struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

template ParameterDefaults(func...) {
import std.traits : FunctionTypeOf;
static if (is(FunctionTypeOf!(func[0]) PT == __parameters)) {
enum ParameterDefaults = (PT[0..1] args) @trusted {
return *&(args[0]);
}();
}
}


The above code works, and prints "3". If you move 
ParameterDefaults to a different module, something like this:


-

import bar;

struct S {}

void f(@S int = 3);

pragma(msg, ParameterDefaults!f.stringof);

-

module bar;

template ParameterDefaults(func...) {
static if (is(typeof(func[0]) PT == __parameters)) {
enum ParameterDefaults = (PT[0..1] args) @trusted {
return *&(args[0]);
}();
}
}
-

Then you get an error message about 'undefined identifier S'. Add 
some kind of S to bar, and you get an error message about S not 
being readable at compile-time or things just work if it is 
readable. It seems the UDA is being looked up in the wrong 
context.


--
  Simen


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 17 April 2020 at 16:40:15 UTC, Jean-Louis Leroy wrote:
Alas the presence of parameter UDAs breaks 
std.traits.ParameterDefaults:


import std.traits;

struct attr;
void f(@attr int);



This part seems fine...


pragma(msg, ParameterDefaults!f.stringof);


It is this, specifically, that causes the problem. Replace it 
with:


void main() {
import std.stdio;
writeln(ParameterDefaults!f.stringof);
}

and it is fine.

So pragma(msg) is doing something really weird, the bug doesn't 
appear to be in Phobos per se, I think it is the compiler doing 
the wrong thing, it seems to me it works inside a function scope 
but not at module scope..



I'd like to understand why taking a slice of __parameters vs 
fetching the first element matters. What is the (meta?) type of 
__parameters[0..1]?


The first element alone becomes a type. The slice maintains the 
magic data inside the compiler; it contains stuff the rest of the 
language cannot express by itself except in parameter lists.


It is weird.

collapses into a string. Makes me think of wave functions in 
quantum mechanics ;-)


well it is dependent on when the compiler observes it so lol


Re: Extracting user defined attributes on function parameters

2020-04-17 Thread Jean-Louis Leroy via Digitalmars-d-learn
Alas the presence of parameter UDAs breaks 
std.traits.ParameterDefaults:


import std.traits;

struct attr;
void f(@attr int);

pragma(msg, ParameterDefaults!f.stringof);

Error:

dmd -c bug.d
bug.d(4): Error: undefined identifier `attr`, did you mean 
variable `ptr`?

/home/jll/dlang/dmd-2.090.1/linux/bin64/../../src/phobos/std/traits.d(1526): 
Error: template instance `std.traits.ParameterDefaults!(f).Get!0LU` error 
instantiating
/home/jll/dlang/dmd-2.090.1/linux/bin64/../../src/phobos/std/traits.d(1529):
instantiated from here: `Impl!0LU`
bug.d(6):instantiated from here: `ParameterDefaults!(f)`
bug.d(6):while evaluating `pragma(msg, 
ParameterDefaults!(f).stringof)`


I filed a bug report (20744). And examined the code of 
ParameterDefaults. I think I understand how it works, for the 
most part, but I haven't been able to find a fix yet.


I'd like to understand why taking a slice of __parameters vs 
fetching the first element matters. What is the (meta?) type of 
__parameters[0..1]? I think I'd need to make a copy of it, minus 
the UDAs tucked at the beginning. But I haven't found a way of 
splitting it into smaller components. I tried using indexation 
and variadic template parameters, but it always collapses into a 
string. Makes me think of wave functions in quantum mechanics ;-)




Re: Extracting user defined attributes on function parameters

2020-04-15 Thread Jean-Louis Leroy via Digitalmars-d-learn

Thanks to both of you!

As part of implementing full support for attributes in 
openmethods, I am developing a reflection library. That helped a 
lot.


is() is a bit weird, but I described it in my "D Cookbook" to 
some success...


I am going to order it...even though it is not available on 
Kindle ;-)




Re: Extracting user defined attributes on function parameters

2020-04-14 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Apr 15, 2020 at 12:01:51AM +, Adam D. Ruppe via Digitalmars-d-learn 
wrote:
[...]
> is() is a bit weird, but I described it in my "D Cookbook" to some
> success... and writing that description helped me make sense of it.
> The docs list like seven forms of it, but they are mostly just one big
> thing with a lot of optional pieces you can leave out, coupled with a
> little bit of magic when you use certain keywords, like __parameters.

is(T params == __parameters) is one of the most evil arcane black magic
corners of D, as I wrote here:


https://forum.dlang.org/post/mailman.1197.1379014886.1719.digitalmars-d-le...@puremagic.com

It feels like it was shoehorned into is() because that was the most
convenient place at the time, but it's really a strange arcane beast
that has its own quirky behaviours that are different from anything else
I've seen in D.


T

-- 
The irony is that Bill Gates claims to be making a stable operating
system and Linus Torvalds claims to be trying to take over the world. --
Anonymous


Re: Extracting user defined attributes on function parameters

2020-04-14 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 21:54:14 UTC, Jean-Louis Leroy wrote:

O.kay. It looks like `is` is D's Swiss army chainsaw.


Aye, is and __traits are the two built-in compile-time reflection 
avenues. The phobos std.traits things (for the most part, look at 
the source for the default parameter values thing and lol you'll 
see some of them get quite involved) wrap them.


is() is a bit weird, but I described it in my "D Cookbook" to 
some success... and writing that description helped me make sense 
of it. The docs list like seven forms of it, but they are mostly 
just one big thing with a lot of optional pieces you can leave 
out, coupled with a little bit of magic when you use certain 
keywords, like __parameters.


https://dlang.org/spec/expression.html#is_expression

I like to think of it as a kind of magic variable declaration

is(SomeExistingType yourOptionalIdenfier == some_optional_pattern)

(or you can use : instead of == for a looser match. == is 
equality, and : indicates implicit conversion, like how class Foo 
: Interface can implicitly convert to Interface, so `is(Foo : 
Interface)` passes.



If you leave off both the ident and the pattern, it just check is 
the type is a type:


static if(is(Object)) // passed because Object is a type

static if(is(10)) // fails because 10 isn't a type, it is a value

static if(is(adasdsa)) // fails because undefined identifier


If you provide the optional identifier, it aliases the match 
inline for you. I think of the syntax as being like a variable 
declaration. So just like


int a; // defines a new variable with the name "a"

static if(is(Object a)) // defines a new alias with the name "a" 
being the same as Object




Then you add on the pattern. These are generally written like the 
variable declaration too, but you can define placeholders. Simple 
example:


static if(is(typeof(a) == int))

more complex example:

static if(is(typeof(a) == T[], T))


In that one, the pattern is "T[]", looking like a type, but then 
since I specified ", T" afterward, it means T is a placeholder.


So that would match if typeof(a) is some kind of array, and then 
T gets the element type.


int[] a;
static if(is(typeof(a) == T[], T)) // passes because a is an 
array, T == int



Those can get pretty complex because you're allowed to add as 
many placeholders as you need for an arbitrarily complex pattern, 
though I prefer to keep it kinda simple and use two levels of 
static if to cover more complicated things.


Then the last magic is the pattern on the right-hand side can be 
various keywords.


static if(is(Object == class))

passes if Object is a class. You can also do that with struct, 
interface, union, const, immutable, and shared.


But if you look at the docs, you see there are a few other magic 
keywords too, like `enum`, return, function, delegate, super, and 
__parameters. They still match what you expect basically - if it 
is a function pointer, or an enum, etc., but the real magic is 
they change what the alias you can define in the is() expression 
refers to. So then it isn't just a convenience alias for the 
condition, it actually becomes an aspect of that type, like the 
return type, or the params, or the parent class.


So yes a swiss army chainsaw :P but once you know its few tricks 
and patterns it isn't as hard as the docs make it look.


Re: Extracting user defined attributes on function parameters

2020-04-14 Thread Jean-Louis Leroy via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 21:44:51 UTC, Adam D. Ruppe wrote:
On Tuesday, 14 April 2020 at 21:35:12 UTC, Jean-Louis Leroy 
wrote:

I can see them:


There's some weird tricks to it. Check out my old blog sidebar 
about it here:


http://dpldocs.info/this-week-in-d/Blog.Posted_2019_02_11.html#how-to-get-uda-on-a-function-param


O.kay. It looks like `is` is D's Swiss army chainsaw. Yeah I 
never read the `is` doc properly. Now I am beginning to 
understand how `std.traits.Parameters` works.


Thanks!



Re: Extracting user defined attributes on function parameters

2020-04-14 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 14 April 2020 at 21:35:12 UTC, Jean-Louis Leroy wrote:

I can see them:


There's some weird tricks to it. Check out my old blog sidebar 
about it here:


http://dpldocs.info/this-week-in-d/Blog.Posted_2019_02_11.html#how-to-get-uda-on-a-function-param



Extracting user defined attributes on function parameters

2020-04-14 Thread Jean-Louis Leroy via Digitalmars-d-learn

I can see them:

import std.traits;

struct foo;
struct bar;

void f(@foo int, @foo @bar @("baz") real);

pragma(msg, Parameters!f);
// (@(foo) int, @(tuple(tuple(foo), tuple(bar)), 
tuple("baz")) real)


...but I cannot find how to get hold of them:

pragma(msg, (Mystery!f)[0]); // foo
pragma(msg, __traits(mystery, f)[0]); // foo

And besides the structure looks weird for the second argument. 
It's as if the UDAs were applied to one another, from left to 
right.


I did search the documentation and google for 1/2 hour.




Re: linker aliases to carry dlang attributes for externs

2020-04-12 Thread Bruce Carneal via Digitalmars-d-learn

On Sunday, 12 April 2020 at 23:14:42 UTC, Bruce Carneal wrote:
Could dlang compilers emit aliases for extern(C) and 
extern(C++) routines that would carry dlang specific 
information?  (@safe, @nogc, nothrow, ...)


I'm thinking two symbols.  The first as per normal C/C++, and 
the second as per normal dlang with a "use API {C, C++, ...}" 
suffix.


ABI, not API.



linker aliases to carry dlang attributes for externs

2020-04-12 Thread Bruce Carneal via Digitalmars-d-learn
Could dlang compilers emit aliases for extern(C) and extern(C++) 
routines that would carry dlang specific information?  (@safe, 
@nogc, nothrow, ...)


I'm thinking two symbols.  The first as per normal C/C++, and the 
second as per normal dlang with a "use API {C, C++, ...}" suffix.




Re: Conditional Attributes

2020-02-21 Thread Marcel via Digitalmars-d-learn

On Thursday, 20 February 2020 at 17:41:54 UTC, Dennis wrote:

On Tuesday, 18 February 2020 at 17:11:55 UTC, Marcel wrote:
Say I have a struct where every member function can either be 
static or not depending on a template parameter. Is there a 
simple way to do this?


The best I can think of is:

```
mixin template maybeStatic() {
void foo() {
// implementation
}
}

struct S(bool condition) {
static if (condition) {
static {
mixin maybeStatic;
}
} else {
mixin maybeStatic;
}
}
```

What do you need this for? It seems like an unusual situation 
to me.


That will do, thank you!
I'm making an allocator library similar to what Andrei 
Alexandrescu presented at CppCon. Since some allocators may not 
have state, those that inherit* from them may need to have every 
member function marked as static.


*I'm using mixins instead of inheritance.


Re: Conditional Attributes

2020-02-21 Thread Marcel via Digitalmars-d-learn
On Friday, 21 February 2020 at 01:41:21 UTC, Steven Schveighoffer 
wrote:

On 2/18/20 12:11 PM, Marcel wrote:

Hello!

Say I have a struct where every member function can either be 
static or not depending on a template parameter. Is there a 
simple way to do this? Like, for example:


struct Foo(Condition)
{
    static if (Condition) static:

    void Bar() {}
    void Baz() {}

}


Since D conditional compilation must always be a valid 
declaration or statement, you cannot do something like this.


The closest you can do is to use mixins, which means you have 
to write everything inside strings.


It has been proposed quite a few times to have a way to 
enable/disable attributes based on a compile-time boolean. But 
it's never come close to getting included.


-Steve


That's a shame...


Re: Conditional Attributes

2020-02-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/18/20 12:11 PM, Marcel wrote:

Hello!

Say I have a struct where every member function can either be static or 
not depending on a template parameter. Is there a simple way to do this? 
Like, for example:


struct Foo(Condition)
{
    static if (Condition) static:

    void Bar() {}
    void Baz() {}

}


Since D conditional compilation must always be a valid declaration or 
statement, you cannot do something like this.


The closest you can do is to use mixins, which means you have to write 
everything inside strings.


It has been proposed quite a few times to have a way to enable/disable 
attributes based on a compile-time boolean. But it's never come close to 
getting included.


-Steve


Re: Conditional Attributes

2020-02-20 Thread Dennis via Digitalmars-d-learn

On Tuesday, 18 February 2020 at 17:11:55 UTC, Marcel wrote:
Say I have a struct where every member function can either be 
static or not depending on a template parameter. Is there a 
simple way to do this?


The best I can think of is:

```
mixin template maybeStatic() {
void foo() {
// implementation
}
}

struct S(bool condition) {
static if (condition) {
static {
mixin maybeStatic;
}
} else {
mixin maybeStatic;
}
}
```

What do you need this for? It seems like an unusual situation to 
me.


Conditional Attributes

2020-02-18 Thread Marcel via Digitalmars-d-learn

Hello!

Say I have a struct where every member function can either be 
static or not depending on a template parameter. Is there a 
simple way to do this? Like, for example:


struct Foo(Condition)
{
   static if (Condition) static:

   void Bar() {}
   void Baz() {}

}


Re: How to "Inherit" the attributes from a given callable argument?

2019-06-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 13, 2019 3:49:04 AM MDT Jacob Carlborg via Digitalmars-d-
learn wrote:
> On 2019-06-12 22:42, Mek101 wrote:
> > I didn't know it applied to templates other than lambdas.
> >
> > Thank you for your explanation.
>
> It applies to templates, lambdas (which basically are templates) and
> nested functions.

It also now applies to auto return functions, though that's a more recent
change.

- Jonathan M Davis





Re: How to "Inherit" the attributes from a given callable argument?

2019-06-13 Thread Jacob Carlborg via Digitalmars-d-learn

On 2019-06-12 22:42, Mek101 wrote:

I didn't know it applied to templates other than lambdas.

Thank you for your explanation.


It applies to templates, lambdas (which basically are templates) and 
nested functions.


--
/Jacob Carlborg


Re: How to "Inherit" the attributes from a given callable argument?

2019-06-12 Thread Mek101 via Digitalmars-d-learn

I didn't know it applied to templates other than lambdas.

Thank you for your explanation.


Re: How to "Inherit" the attributes from a given callable argument?

2019-06-12 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jun 12, 2019 at 07:46:12PM +, Mek101 via Digitalmars-d-learn wrote:
[...]
> > public size_t indexOf(alias pred = "a == b", Range)(Range array)
> > {
> > alias predicate = unaryFun!pred;
> > for(size_t i = 0; i < array.length; i++)
> > if(predicate(array[i]))
> > return i;
> > return size_t.max;
> > }
> 
> Say that I may want to use the function in a @nogc scope, providing a
> @nogc callable, but I also want to reuse the same code in managed
> scope while passing a delegate: how can I apply the attributes of the
> given callable to the function so that they're automatically
> determined at compile time?
[...]

You don't need to do anything special; indexOf, as you declared it, is
already a template function, so the compiler should automatically apply
attribute inference to it. So if pred is @nogc, and the implementation
of indexOf itself doesn't invoke the GC, the compiler should
automatically infer @nogc for you.

One safeguard that you might want to consider is to write a @nogc
unittest, something like this:

@nogc unittest
{
...
auto result = indexOf!(...)(...);
...
}

The @nogc annotation on the unittest ensures that as long as the pred
argument to indexOf is @nogc, indexOf itself will also be @nogc. This
prevents future changes from accidentally introducing GC dependent code
in the implementation of indexOf, while at the same time not explicitly
marking indexOf as @nogc (only the unittest is annotated, not the
function itself) allows you to use it with GC-dependent predicates as
well.


T

-- 
Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubert


How to "Inherit" the attributes from a given callable argument?

2019-06-12 Thread Mek101 via Digitalmars-d-learn

I'll try to be straight.

I have the following function:


public size_t indexOf(alias pred = "a == b", Range)(Range array)
{
alias predicate = unaryFun!pred;
for(size_t i = 0; i < array.length; i++)
if(predicate(array[i]))
return i;
return size_t.max;
}


Say that I may want to use the function in a @nogc scope, 
providing a @nogc callable, but I also want to reuse the same 
code in managed scope while passing a delegate: how can I apply 
the attributes of the given callable to the function so that 
they're automatically determined at compile time?


I know of std.traits.SetFunctionAttributes and 
std.traits.FunctionAttributes, but I have no idea on how to apply 
them to solve this. Perhaps I should declare indexOf as a 
template?


Re: Do @property attributes not allow postincrement operators

2019-04-13 Thread Jamie via Digitalmars-d-learn

On Sunday, 14 April 2019 at 02:11:52 UTC, Mike Franklin wrote:

On Sunday, 14 April 2019 at 01:54:39 UTC, Jamie wrote:

Do @property attributes not allow postincrement operators?
...


It's a long standing issue (going on 7 years old)
...
I plan on getting to it, but there are other pressing things 
I'm trying to get out of the way.


Mike


Thanks Mike -- appears I didn't do a thorough enough search for 
this behaviour. Looking forward to it being implemented, cheers.


Re: Do @property attributes not allow postincrement operators

2019-04-13 Thread Mike Franklin via Digitalmars-d-learn

On Sunday, 14 April 2019 at 01:54:39 UTC, Jamie wrote:

Do @property attributes not allow postincrement operators?

import std.stdio;

struct Foo {
@property bar() { return 10; }
@property bar(int x) { writeln(x); }
}

void main()
{
Foo foo;
writeln(foo.bar); // actually calls foo.bar();
foo.bar = 10; // calls foo.bar(10);

// following doesn't work
foo.bar++; // would expect this to call foo.bar(foo.bar() + 
1);

// have to use:
foo.bar = foo.bar + 1;
writeln(foo.bar);
}


It's a long standing issue (going on 7 years old)

https://issues.dlang.org/show_bug.cgi?id=8006

There's an implementation at 
https://github.com/dlang/dmd/pull/7079


It requires a DIP, which you can find at 
https://github.com/dlang/DIPs/pull/97


However, in preparing that DIP other issues were discovered with 
@property, so we need to create a DIP to fix those issues first.


I plan on getting to it, but there are other pressing things I'm 
trying to get out of the way.


Mike


Do @property attributes not allow postincrement operators

2019-04-13 Thread Jamie via Digitalmars-d-learn

Do @property attributes not allow postincrement operators?

import std.stdio;

struct Foo {
@property bar() { return 10; }
@property bar(int x) { writeln(x); }
}

void main()
{
Foo foo;
writeln(foo.bar); // actually calls foo.bar();
foo.bar = 10; // calls foo.bar(10);

// following doesn't work
foo.bar++; // would expect this to call foo.bar(foo.bar() + 
1);

// have to use:
foo.bar = foo.bar + 1;
writeln(foo.bar);
}


Re: Get attributes of a field?

2019-04-02 Thread Jacob Carlborg via Digitalmars-d-learn

On 2019-04-02 15:23, Alex wrote:

__traits(getAttributes, T)

Requires a type and a field is unfortunately not a type ;/


enum attr;

struct Foo
{
@attr int a;
}

void main()
{
alias a = __traits(getAttributes, Foo.a);
}

--
/Jacob Carlborg


Re: Get attributes of a field?

2019-04-02 Thread Andre Pany via Digitalmars-d-learn

On Tuesday, 2 April 2019 at 13:36:47 UTC, Alex wrote:

On Tuesday, 2 April 2019 at 13:23:37 UTC, Alex wrote:

__traits(getAttributes, T)

Requires a type and a field is unfortunately not a type ;/


I'd like to be able to get the attributes without having to 
instantiate the base type because that is problematic and I see 
no reason why it has to be instantiated to get CT values.


Could you provide a full example for this issue and for your 
other message? That makes it easier to help you


Kind regards
Andre


Re: Get attributes of a field?

2019-04-02 Thread Alex via Digitalmars-d-learn

On Tuesday, 2 April 2019 at 13:23:37 UTC, Alex wrote:

__traits(getAttributes, T)

Requires a type and a field is unfortunately not a type ;/


I'd like to be able to get the attributes without having to 
instantiate the base type because that is problematic and I see 
no reason why it has to be instantiated to get CT values.


Get attributes of a field?

2019-04-02 Thread Alex via Digitalmars-d-learn

__traits(getAttributes, T)

Requires a type and a field is unfortunately not a type ;/



Re: How to attach function attributes to delegate type?

2019-03-01 Thread Vijay Nayar via Digitalmars-d-learn

On Wednesday, 27 February 2019 at 20:45:33 UTC, Alex wrote:
On Wednesday, 27 February 2019 at 20:03:15 UTC, Q. Schroll 
wrote:
For any type constructors like const, I can use ConstOf!T to 
get `T` with const attached. For a delegate/function type DG, 
e.g. int delegate(int), how can I get the @safe version of 
that type, i.e. int delegate(int) @safe?


I tried

alias SafeOf(DG) = DG @safe;

but it didn't compile.

The case is not @safe-specific; it's the same for all function 
attributes.


At https://p0nce.github.io/d-idioms/

there is a demonstration for @nogc:

´´´
import std.traits;

// Casts @nogc out of a function or delegate type.
auto assumeNoGC(T) (T t) if (isFunctionPointer!T || 
isDelegate!T)

{
enum attrs = functionAttributes!T | FunctionAttribute.nogc;
return cast(SetFunctionAttributes!(T, functionLinkage!T, 
attrs)) t;

}
´´´

Didn't try this for other cases, however...


When I need particular attributes, such as for a comparator, but 
also need to pass in a function as a template argument, one 
approach I've started to adopt is to only call this function from 
within a wrapper that has all the properties I want.


For example:

import std.stdio;

class MyThing(T, alias LessF) {
  // This wrapper defines the conditions for a valid LessF.
  @safe @nogc
  private static bool less(in T t1, in T t2) {
return LessF(t1, t2);
  }
}

void main()
{
  MyThing!(int, (a, b) => a < b) a;  // Compiles fine!
  MyThing!(int, (a, b) {
writeln("Not @nogc!");  // Compiler error!
return a < b;
  }) b;
}

The error looks like this, which is fairly readable too.

onlineapp.d(6): Error: `@nogc` function 
`onlineapp.main.MyThing!(int, (a, b)

{
writeln("Not @nogc!");
return a < b;
}
).MyThing.less` cannot call non-@nogc function


Re: How to attach function attributes to delegate type?

2019-02-27 Thread Alex via Digitalmars-d-learn

On Wednesday, 27 February 2019 at 20:03:15 UTC, Q. Schroll wrote:
For any type constructors like const, I can use ConstOf!T to 
get `T` with const attached. For a delegate/function type DG, 
e.g. int delegate(int), how can I get the @safe version of that 
type, i.e. int delegate(int) @safe?


I tried

alias SafeOf(DG) = DG @safe;

but it didn't compile.

The case is not @safe-specific; it's the same for all function 
attributes.


At https://p0nce.github.io/d-idioms/

there is a demonstration for @nogc:

´´´
import std.traits;

// Casts @nogc out of a function or delegate type.
auto assumeNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T)
{
enum attrs = functionAttributes!T | FunctionAttribute.nogc;
return cast(SetFunctionAttributes!(T, functionLinkage!T, 
attrs)) t;

}
´´´

Didn't try this for other cases, however...


How to attach function attributes to delegate type?

2019-02-27 Thread Q. Schroll via Digitalmars-d-learn
For any type constructors like const, I can use ConstOf!T to get 
`T` with const attached. For a delegate/function type DG, e.g. 
int delegate(int), how can I get the @safe version of that type, 
i.e. int delegate(int) @safe?


I tried

alias SafeOf(DG) = DG @safe;

but it didn't compile.

The case is not @safe-specific; it's the same for all function 
attributes.


Re: what are the rules for @nogc and @safe attributes inference?

2018-11-30 Thread Neia Neutuladh via Digitalmars-d-learn
On Fri, 30 Nov 2018 22:10:11 +, ikod wrote:
> Thanks for explanation, got it.
> 
> My case is actually
> 
> interface I(K,V)
> {
>  int get()(K);
> }

Interface functions must be abstract. Templated functions are implicitly 
final. Final things can't be abstract.

If there's something about types K and V that determine whether you should 
be able to use the GC or not, you'll have to encode that explicitly.


  1   2   3   4   >