Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-10 Thread Simon via Digitalmars-d-learn

On Saturday, 9 March 2019 at 09:12:13 UTC, Dennis wrote:

On Friday, 8 March 2019 at 11:42:11 UTC, Simon wrote:
Thanks, this works flawlessly. Out of interest: what is the 
"enum" doing there? I had the exact same behaviour in a 
function before, that I only called at compile-time, so why 
did it complain then? Can I somehow tell the compiler that a 
function should only be available at compile-time?


The enum (which in D is not only for enumerations, but also for 
"manifest constants") ensures it is evaluated at compile-time, 
since things are only evaluated at compile-time if they have to.

See also Adam D. Ruppe's post in this thread:
https://forum.dlang.org/post/blaawtdhljjantvga...@forum.dlang.org


Thanks!


Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-09 Thread Dennis via Digitalmars-d-learn

On Friday, 8 March 2019 at 11:42:11 UTC, Simon wrote:
Thanks, this works flawlessly. Out of interest: what is the 
"enum" doing there? I had the exact same behaviour in a 
function before, that I only called at compile-time, so why did 
it complain then? Can I somehow tell the compiler that a 
function should only be available at compile-time?


The enum (which in D is not only for enumerations, but also for 
"manifest constants") ensures it is evaluated at compile-time, 
since things are only evaluated at compile-time if they have to.

See also Adam D. Ruppe's post in this thread:
https://forum.dlang.org/post/blaawtdhljjantvga...@forum.dlang.org


Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-08 Thread Simon via Digitalmars-d-learn

On Thursday, 7 March 2019 at 21:50:17 UTC, Johannes Loher wrote:

```
enum profile_scope(string name) = "import core.stdc.stdio : 
printf;

printf(\""
~ name ~ "\n\"); scope(exit) printf(\"" ~ name ~ "\n\");";

extern (C) void main()
{
mixin(profile_scope!"func1");
}

```
This uses string concatenation only at compile time and not 
during run
time, so it does not require the garbage collector and is 
compatible

with betterC :)


Thanks, this works flawlessly. Out of interest: what is the 
"enum" doing there? I had the exact same behaviour in a function 
before, that I only called at compile-time, so why did it 
complain then? Can I somehow tell the compiler that a function 
should only be available at compile-time?


Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Johannes Loher via Digitalmars-d-learn
Am 07.03.19 um 22:50 schrieb Johannes Loher:
> [...]

As a small addition, if you always want to pass the function name as a
parameter, you can simplify this to the following:

```
enum profile_scope(string name = __FUNCTION__) = "import core.stdc.stdio
: printf; printf(\""
~ name ~ "\n\"); scope(exit) printf(\"" ~ name ~ "\n\");";

extern (C) void main()
{
mixin(profile_scope!());
foo();
}

extern (C) void foo() {
mixin(profile_scope!());
}
```
This will print
```
main.main
main.foo
main.foo
main.main
```
to the commandline.



Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Johannes Loher via Digitalmars-d-learn
Am 07.03.19 um 22:21 schrieb Simon:
> 
> Is there a way to achieve this while compiling with -betterC? I use a
> custom string struct right now, and your version needs TypeInfo,
> concatening using ~ needs the garbage collector. I have the feeling D is
> really not agreeing with the way I want to do things. If this is not
> possible, I will just roll with the Adam's struct solution.
> 

Using Adams struct solution is perfectly fine. I believe it is probably
the cleaner solution overall.

My solution depends on TypeInfo because format does. I used format
because it makes the string more readable. You can avoid this and use
string concatenation in combination with providing the function name as
template parameter instead:

```
enum profile_scope(string name) = "import core.stdc.stdio : printf;
printf(\""
~ name ~ "\n\"); scope(exit) printf(\"" ~ name ~ "\n\");";

extern (C) void main()
{
mixin(profile_scope!"func1");
}

```
This uses string concatenation only at compile time and not during run
time, so it does not require the garbage collector and is compatible
with betterC :)


Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Simon via Digitalmars-d-learn

On Thursday, 7 March 2019 at 20:34:48 UTC, Johannes Loher wrote:


auto profile_scope(string name)
{
import std.format : format;
return q{import std.stdio : writeln; writeln("%1$s"); 
scope(exit)

writeln("%1$s");}.format(name);
}

void main()
{
mixin(profile_scope("func1"));
}


Is there a way to achieve this while compiling with -betterC? I 
use a custom string struct right now, and your version needs 
TypeInfo, concatening using ~ needs the garbage collector. I have 
the feeling D is really not agreeing with the way I want to do 
things. If this is not possible, I will just roll with the Adam's 
struct solution.




Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Johannes Loher via Digitalmars-d-learn
Am 07.03.19 um 21:07 schrieb Simon:
> Hello,
> 
> I am currently porting the frontend of my instrumenting profiler to D.
> It features a C++-makro that profiles the time between entering and
> leaving a scope (achieved with con-/destructors in C++). Since D has
> scopeguards, I hoped to achieve this by creating a mixin that generates
> the following code:
> 
> measure("func1");
> scope(exit) measure("func1");
> 
> Since I of course don't want to type a mixin for that everytime I want
> to use it, I tried to alias it:
> 
> import std.meta : Alias;
> alias profile_scope(string name) = Alias!(mixin("measure(\"" ~ name ~
> "\"); scope(exit) measure(\"" ~ name ~ "\");"));
> 
> I expected this to generate the code above by typing
> profile_scope("func1") in my programm. However the compiler (dmd) gives
> me the following error:
> 
> source\main.d(24): Error: template plattform.profile_scope cannot deduce
> function from argument types !()(string), candidates are:
> source\plattform.d(262):    plattform.profile_scope(string name)
> 
> This looks like a deduction/overload kind of error, which has me
> completly confused since there is no other identifier of the name
> "profile_scope" in my programm and the error message shows only one
> candidate.
> 
> Is there any way I can achive generating those two statements using only
> something that effectively looks like a function call/C-macro with an
> argument?
The error you are seeing is due to the fact that you pass "func1" as
runtime parameter instead of as a teamplate parameter. You would need to
do `profile_scope!("func1");`. However, this will still not work and
you'll get an error message similar to this:
```
main.d(4): Error: incomplete mixin expression writeln("func1");
scope(exit) writeln("func1");
main.d(8): Error: template instance `main.profile_scope!"func1"` error
instantiating
```

The underlying problem is that you can only alias expressions, i.e. you
cannot use alias to generate macro like functionality.

`measure("func1"); scope(exit) measure("func1");` is not an expression,
it is simply a statement, so the alias cannot work.

If you want to inject code directly at some place, basically your only
option is to use a string mixin. I understand that you do not want to
write `mixin` all the time, but to me, this does not look that bad:
```
auto profile_scope(string name)
{
import std.format : format;
return q{import std.stdio : writeln; writeln("%1$s"); scope(exit)
writeln("%1$s");}.format(name);
}

void main()
{
mixin(profile_scope("func1"));
}
```
(replace writeln with your appropriate function call, "measure" in your
example).



Re: Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 7 March 2019 at 20:07:27 UTC, Simon wrote:

measure("func1");
scope(exit) measure("func1");


I would suggest just using a struct. Make its constructor do the 
first measure, and its destructor do the second measure.


I betcha you can avoid mixin entirely.


Aliasing a mixin (or alternative ways to profile a scope)

2019-03-07 Thread Simon via Digitalmars-d-learn

Hello,

I am currently porting the frontend of my instrumenting profiler 
to D. It features a C++-makro that profiles the time between 
entering and leaving a scope (achieved with con-/destructors in 
C++). Since D has scopeguards, I hoped to achieve this by 
creating a mixin that generates the following code:


measure("func1");
scope(exit) measure("func1");

Since I of course don't want to type a mixin for that everytime I 
want to use it, I tried to alias it:


import std.meta : Alias;
alias profile_scope(string name) = Alias!(mixin("measure(\"" ~ 
name ~ "\"); scope(exit) measure(\"" ~ name ~ "\");"));


I expected this to generate the code above by typing 
profile_scope("func1") in my programm. However the compiler (dmd) 
gives me the following error:


source\main.d(24): Error: template plattform.profile_scope cannot 
deduce function from argument types !()(string), candidates are:
source\plattform.d(262):plattform.profile_scope(string 
name)


This looks like a deduction/overload kind of error, which has me 
completly confused since there is no other identifier of the name 
"profile_scope" in my programm and the error message shows only 
one candidate.


Is there any way I can achive generating those two statements 
using only something that effectively looks like a function 
call/C-macro with an argument?