Re: How to get a function name (string) @ compile time

2018-12-08 Thread Andrew Pennebaker via Digitalmars-d-learn

On Monday, 3 November 2008 at 12:29:16 UTC, Simen Kjaeraas wrote:
On Mon, 03 Nov 2008 12:33:05 +0100, Denis Koroskin 
<2kor...@gmail.com> wrote:


On Mon, 03 Nov 2008 04:11:20 +0300, Daniel Ribeiro Maciel 
 wrote:



Denis Koroskin Wrote:


On Mon, 03 Nov 2008 01:59:56 +0300, Daniel Ribeiro Maciel
 wrote:

> How do we get a function name (string) @ compile time?
>
> I need to do stuff like (in C)
>
> #include 
>
> #define HELLO( func ) \
>   printf( "calling " #func "\n" ); \
>   func();
>
> void foo()
> {
>printf( "@foo" );
> }
>
> int main()
> {
>HELLO( foo );
>printf( "\n" );
> }
>
> The output is:
> calling foo
> @foo
>
> Thanks in advance,
> Daniel
>

Just in case you know little D here is the source code, 
explanation and

comparison to C++:

import std.stdio; // this is used to import writefln() - a 
function

similar to printf (but typesafe)

// this is a template function that takes almost anything 
(close to C++

templates and C macros)
void print(alias functionName)()
{
 // stringof is used to take a string representation of 
the identifier

 writefln("Calling ", functionName.stringof);

 // let's invoke it! This will succeed if functionName 
is a function,

pointer to function,
 // delegate or an object that have overloaded opCall() 
(similar to C++

operator())
 functionName();
}

void foo()
{
 writefln("@foo"); // same as printf("@foo);
}

void main()
{
 // foo is a global (free) function. it is passed to the 
template

function.
 // In C++ you would do print(); (but C++ doesn't 
support

specializing
 // templates with functions nor does it have .stringof)
 print!(foo);
}


Thanx a lot! It worked for some functions.

I found a problem though. If we change foo to:

void foo( double i )
{
 writefln("@foo ", i );
}

the compiler yields an error:

test.d(30): function app.sandbox.main.foo (double i) does not 
match parameter types ()

test.d(30): Error: expected 1 arguments, not 0]

line 30 is this:  writefln("Calling ", 
functionName.stringof);


Is this supposed to be a bug?

Best regards,
Daniel



Yes, it is. For some reason it tries to evaluate function 
first and *then* take the stringof property (that is of the 
returned value), i.e. it rewrites it as 
"functionName().stringof". I have written about this bug 4 
months ago ("Omittable parens is an evil" thread) but it is 
not fixed yet.


That's not the only error here. Your template function also 
calls
foo with no arguments on  the line below that bug. Fixing that 
would
probably include the ParameterTypeTuple and ReturnType 
templates.


Er, when I try to use either foo.stringof, or __trait(identifier, 
foo), I always get that binding name, rather than the original 
function name, sad panda.


I can only print out the current variable name, but I want to 
print the name of the function declaration, no matter how deeply 
I pass that first function pointer into different calls :/


Re: dmd -unittest works poorly with executables

2018-12-08 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 08 Dec 2018 20:16:09 +, Andrew Pennebaker wrote:
> I think it's lame to have to use magical code like `version(unittest) {}
> else` to guard our main functions, when we run unit tests. Could D go
> ahead and do the right thing, automatically shadowing our main functions
> when the unit tests are run?

The original intent was for unittests to run before main(). Your debug / 
test builds always run the unittests. This is awkward because unittests 
might sometimes actually be heavier tests that talk to a database or write 
to local files or change global state that would be used in main().

The normal technique with dub is to put *only* main() in app.d. Sometimes 
I take that a step further: I put a runMain() function somewhere in my 
project, and app.d's main() just calls that. Dub automatically excludes 
app.d from the unittest build. Minimum possible code outside the tested 
zone.

Not necessarily awesome, but we do have workarounds.


Re: dmd -unittest works poorly with executables

2018-12-08 Thread Paul Backus via Digitalmars-d-learn
On Saturday, 8 December 2018 at 20:16:09 UTC, Andrew Pennebaker 
wrote:
I think it's lame to have to use magical code like 
`version(unittest) {} else` to guard our main functions, when 
we run unit tests. Could D go ahead and do the right thing, 
automatically shadowing our main functions when the unit tests 
are run?


The correct place to submit an enhancement request like this is 
the D issue tracker at issues.dlang.org.


dmd -unittest works poorly with executables

2018-12-08 Thread Andrew Pennebaker via Digitalmars-d-learn
I think it's lame to have to use magical code like 
`version(unittest) {} else` to guard our main functions, when we 
run unit tests. Could D go ahead and do the right thing, 
automatically shadowing our main functions when the unit tests 
are run?


Re: cant run unittests

2018-12-08 Thread Andrew Pennebaker via Digitalmars-d-learn

On Saturday, 16 July 2016 at 20:22:15 UTC, Seb wrote:

On Thursday, 14 July 2016 at 10:13:38 UTC, dom wrote:

On Thursday, 14 July 2016 at 00:33:50 UTC, ethgeh wrote:

On Wednesday, 13 July 2016 at 19:41:53 UTC, dom wrote:
how can i run my unittests for a dynamic library? some weird 
conflict is reported between main functions, my project 
doesnt contain any main function.


[...]


try to put this before the main of your application:

  "version(unittest){} else"

it looks like the default unittest config implies the switch 
"-main".


as i said my project doesnt contain a main() function


Are you sure? The error message states exactly this. Could you 
reduce the project to a single file and upload it somewhere (e. 
g. github).


I am getting the same error for my projects. I tried prefacing my 
main functions with the version(unittest) {} else snippet (which 
we really shouldn't have to do!!!) but anyway that didn't change 
the behavior of dub test at all.


Re: Library settings, best practices?

2018-12-08 Thread Adam D. Ruppe via Digitalmars-d-learn
On Saturday, 8 December 2018 at 16:58:24 UTC, Vladimirs Nordholm 
wrote:
Is there a best practice to enabling specific parts of a 
library?


For my terminal library, I put it all in a struct. Then the user 
gets to choose how to initialize it, and its destructor gets a 
chance to cleanup when done. The terminal object also contains 
its methods so you feel like you are getting something out of it 
by using them.


I know you prefer not to have the user call initializer 
functions, but I really do think it is the cleanest way to do it.



Alternatively, you could perhaps have it keep an internal 
is_initialized flag and lazily call init on your other function 
calls if it is not already done. Then if the user wants to 
customize settings, they just call init before calling anything 
else, and if not they skip the init call and it gets default 
setup first time they try to use it.


Library settings, best practices?

2018-12-08 Thread Vladimirs Nordholm via Digitalmars-d-learn

Hello.

Pre-rant:
-
I have a library to aid in development for the terminal. This 
library has to initialize some things before it can be used, and 
I run some code in `shared static this(){...}`. I believe in the 
most common case scenario my initializer should be run.


The initializer sets the terminal to allow input and better 
output performance, but makes the terminal not behave as usual.


I believe that sometimes, not all features (input and output) are 
wanted. As mentioned, to optimize output, some ANSI commands are 
called, which messes with ordinary `std.stdio.write(...)`. To get 
input via my library's functions a new thread is created, and 
some other things happen, which might not be desired.


Initially, I did have a initalizer function which the user had to 
call, but I myself often forgot to call the function when making 
a small program, and got stuck because the library didn't 
initalize.


Actual question:

Is there a best practice to enabling specific parts of a library?

Ideally I would prefer to not have them at all, but I myself 
sometime find it necessary to only use a part of the library.


Also as mentioned, I strongly prefer to not have the user call 
initializer functions themselves.


More ranting:
-
Some thoughts I have (which I'm not sure are the best way to 
approach this issue with) are:
* only parts of the library compile (like how `static if(...)` 
and `version (...)` works) depending on what parts should be used.
* put settings in a file in `dub.json/sdl`, or a separate 
settings file.


As a final note, I do not intend for my library to be like vim, 
with a million `#ifdef`s. Only the two main parts (input and 
output) should be available to enable/disable.


These are my thoughts, and any input is highly appreciated. If 
anyone has had experiences with similar issues before, please 
share them.


And if the absolute best way is to have user-called 
(de)initializers, then I guess I have to bite the sour apple ;^)


Best regards,
Vladimirs Nordholm


Re: cannot use local f as parameter to non-global template

2018-12-08 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote:

This compiles fine. However, if I change the match template to:

template match(handlers...) {
auto match(alias f)(Holder!f holder) {
return handlers[0](holder);
}
}

Notice the template parameter of the eponymous match is an 
alias now, and the function parameter is typed as a Holder.


The "de-sugared" version of your second `match` function looks 
like this:


template match(handlers...) {
template match(alias f) {
auto match(Holder!f holder) {
return handlers[0](holder);
}
}
}

Notice the second template nested inside the first. That's the 
"non-gloal template" the error is complaining about.


Re: ElementType of MapResult is a delegate??

2018-12-08 Thread John Chapman via Digitalmars-d-learn

On Saturday, 8 December 2018 at 13:02:00 UTC, Yuxuan Shui wrote:

This surprised me A LOT:

https://d.godbolt.org/z/82a_GZ

So if I call something.map!().array, I get an array of 
delegates? That makes no sense to me.


But in your example, "(a) =>" returns "{return tmp;}", which is a 
delegate. Just write "(a) => tmp", or invoke the delegate by 
turning it into a call: "{return tmp;}()".


ElementType of MapResult is a delegate??

2018-12-08 Thread Yuxuan Shui via Digitalmars-d-learn

This surprised me A LOT:

https://d.godbolt.org/z/82a_GZ

So if I call something.map!().array, I get an array of delegates? 
That makes no sense to me.


Re: Writing Program Without main Function

2018-12-08 Thread Samir via Digitalmars-d-learn
On Saturday, 8 December 2018 at 03:30:30 UTC, Jonathan M Davis 
wrote:
There's one main per program, not per module. Where main lives 
depends on how the program was written, but dub encourages 
putting it in app.d, because that's what it generates when you 
create a new dub project. imports then provide access to other 
modules so that the code doing the importing can use it. You 
can think of it like the module with main being the start of 
the import tree, though it's a bit more complicated than that 
in practice, since modules can be compiled separately, and main 
only has to be there when the program is finally linked. But in 
concept, you have main and the module its in importing other 
modules, which then import other modules, etc. until you get 
all of the code in the program.


- Jonathan M Davis


Thanks for all of the great feedback and explanations, Jonathan!  
Looks like I need to add dub to the list of things I still need 
to learn about.


cannot use local f as parameter to non-global template

2018-12-08 Thread aliak via Digitalmars-d-learn
Hi, I'm wondering about why this happens in a certain situation 
and not another. I have the following code:


struct Holder(alias fun) {
alias T = typeof(fun());
T get() { return fun(); }
alias get this;
}

template match(handlers...) {
auto match(T)(T holder) {
return handlers[0](holder);
}
}

void main() {
int f() { return i7 }
auto value = Holder!f().match!(
(int a) => f()
);
}

This compiles fine. However, if I change the match template to:

template match(handlers...) {
auto match(alias f)(Holder!f holder) {
return handlers[0](holder);
}
}

Notice the template parameter of the eponymous match is an alias 
now, and the function parameter is typed as a Holder.


The error you get is basically because of bug 5710 [0] I guess. 
But I'm confused as to why the same thing doesn't then happen 
when using match(T) as opposed to match(alias f)?


I can work around it by have a template constraint on match of 
course. But still curious why one version works and the other 
not, they both have to access the same frame+context data at the 
end of the day.



[0]: https://issues.dlang.org/show_bug.cgi?id=5710