Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 25 June 2017 at 22:53:07 UTC, Johan Engelen wrote:

I meant semantically no call.


In the existing language, I think version (or static if) at the 
usage and definition points both is as good as you're going to 
get.


unless you use a preprocessor lol

But the good news about version is you could use compiler errors 
about missing name to know where it needs to be (unless there's 
another matching overload in scope[!]). So it would be mildly 
verbose to look at in the code, but not really difficult to get 
right (and you could write it with autocomplete, like vim's 
`:abbr foo version(foo) foo`).



I am now thinking about introducing a noop intrinsic...


That'd be kinda tricky because the arguments would still be 
liable to be evaluated... so the intrinsic would need to cover 
and disable that too and I think you'd be in for a fight to get 
that approved.


Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Johan Engelen via Digitalmars-d-learn

On Sunday, 25 June 2017 at 22:23:44 UTC, Moritz Maxeiner wrote:


The solution obviously does *not* work if you change the 
premise of your question after the fact by artificially 
injecting instructions into all function bodies


I meant semantically no call. I am asking for a little more 
imagination, such that I don't have to specify all obvious 
details. For example, the always inline solution also doesn't 
work well when `foo` takes parameters.


Regardless, perhaps in the meanwhile you've come up with an other 
solution?

I am now thinking about introducing a noop intrinsic...


(read what `-finstrument-functions` does).


:-)




Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 25 June 2017 at 21:55:22 UTC, Johan Engelen wrote:

On Sunday, 25 June 2017 at 16:31:52 UTC, Moritz Maxeiner wrote:


By requiring the compiler to inline the empty foo:


This won't work.


Yes, it does; comment out the call to `foo` and notice no change 
in the assembly in my link.



Semantically, there is still a call


You asked for


no call and no extra code at -O0


and that is exactly what this solution provides.


and e.g. profiling will see it:
https://godbolt.org/g/AUCeuu


The solution obviously does *not* work if you change the premise 
of your question after the fact by artificially injecting 
instructions into all function bodies (read what 
`-finstrument-functions` does).


Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Johan Engelen via Digitalmars-d-learn

On Sunday, 25 June 2017 at 16:31:52 UTC, Moritz Maxeiner wrote:

On Sunday, 25 June 2017 at 15:58:48 UTC, Johan Engelen wrote:

[...]
If version(X) is not defined,  there should be no call and no 
extra code at -O0.

[...]

In C, you could do something like:
```
#if X
  void foo() {..}
#else
  #define foo()
#endif
```

How would you do this in D?


By requiring the compiler to inline the empty foo:


This won't work. Semantically, there is still a call and e.g. 
profiling will see it:

https://godbolt.org/g/AUCeuu

-Johan





Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Johan Engelen via Digitalmars-d-learn

On Sunday, 25 June 2017 at 16:29:20 UTC, Anonymouse wrote:


Am I missing something, or can't you just version both the 
function and the function ćall?


version(X)
void foo() { /* ... */ }

void main()
{
version(X)
{
foo();
}
}


I am hoping for something where "foo()" would just work.
"version(X) foo();" isn't bad, but it adds a lot of noise.

-Johan


Re: Using templates with interfaces

2017-06-25 Thread via Digitalmars-d-learn

On Sunday, 25 June 2017 at 13:32:57 UTC, Andrew Chapman wrote:
I think you've answered the question with "You cannot have 
unimplemented templates in interfaces".  Thanks for the answer.

 I'll rethink the way I'm doing this.

Cheers.


In your case you can probably use something along the lines of:

interface RelationalDBInterface
{
// You can even make this protected
Varaint loadUntypedRow(string sql, Variant[] params);

final T loadRow(T)(string sql, Variant[] params)
{
auto row = loadUntypedRow(sql, params);

enforce(row.hasValue,
this.classID ~ "::loadRow - Query returned an empty 
row");


return row.toStruct!T;
}
}


Re: Using templates with interfaces

2017-06-25 Thread via Digitalmars-d-learn

On Sunday, 25 June 2017 at 13:32:57 UTC, Andrew Chapman wrote:
I think you've answered the question with "You cannot have 
unimplemented templates in interfaces".  Thanks for the answer.

 I'll rethink the way I'm doing this.

Cheers.


Yes, function templates in classes or interfaces are implicitly 
marked as final - meaning that you have to provide an 
implementation. However that is still useful. For example in one 
my projects I wanted to support configuration files written in 
either JSON or SDLang, however since std.json and sdlang-d had 
(as expected) different APIs, I decided to wrap them in classes 
implementing a common interface, so I could solve this in one 
place and be done with it. SDLang and JSON have a tree like 
structure and a common task is that I needed to interpret the 
value at a particular node as a scalar. Here's how I had done it:


interface Node
{
final T get(T)() const
{
static if (isBoolean!T) return getBool();
else static if (isIntegral!T) return to!T(getInt());
else static if (isFloatingPoint!T) return 
to!T(getFloat());

else static if (isSomeString!T) return to!T(getString());
else static assert(0, "Type not supported: " ~ 
T.stringof);

}

const(Node) getChild(string name) const;

protected:
bool getBool() const;
long getInt() const;
double getFloat() const;
string getString() const;
}

That way I could write a generic deserializer that iterates over 
the fields of the object and called the get method like this:


foreach (idx, member; obj.tupleof)
obj.tupleof[idx] =
node.getChild(
typeof(obj).tupleof[idx].stringof)
.get!(typeof(member));


Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 25 June 2017 at 15:58:48 UTC, Johan Engelen wrote:

[...]
If version(X) is not defined,  there should be no call and no 
extra code at -O0.

[...]

In C, you could do something like:
```
#if X
  void foo() {..}
#else
  #define foo()
#endif
```

How would you do this in D?


By requiring the compiler to inline the empty foo:

```
version (Foo)
{
void foo()
{
import std.stdio;
writeln("foo");
}
} else {
pragma(inline, true)
void foo() {}
}

void main(string[] args)
{
foo();
}
```

See [1] for full assembly, shortened output as follows:

```
void example.foo():
ret

_Dmain:
xor eax, eax
mov qword ptr [rsp - 16], rdi
mov qword ptr [rsp - 8], rsi
ret
```

As you can see, while the code for the function itself will still 
be emitted, since it's empty the inlining will result in no 
instructions as the result.


[1] https://godbolt.org/g/RLt6vN


Re: Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Anonymouse via Digitalmars-d-learn

On Sunday, 25 June 2017 at 15:58:48 UTC, Johan Engelen wrote:
How would you solve this problem: do an optional function call 
depending on some version(X). If version(X) is not defined, 
there should be no call and no extra code at -O0.


```
{
...
   foo();  // either compiles to a function call, or to 
_nothing_.

...
}
```

In C, you could do something like:
```
#if X
  void foo() {..}
#else
  #define foo()
#endif
```

How would you do this in D?

I can think of `mixin(foo())` but there is probably a nicer way 
that preserves normal function calling syntax.


Cheers,
  Johan


Am I missing something, or can't you just version both the 
function and the function ćall?


version(X)
void foo() { /* ... */ }

void main()
{
version(X)
{
foo();
}
}


Zero-cost version-dependent function call at -O0.

2017-06-25 Thread Johan Engelen via Digitalmars-d-learn
How would you solve this problem: do an optional function call 
depending on some version(X). If version(X) is not defined, there 
should be no call and no extra code at -O0.


```
{
...
   foo();  // either compiles to a function call, or to _nothing_.
...
}
```

In C, you could do something like:
```
#if X
  void foo() {..}
#else
  #define foo()
#endif
```

How would you do this in D?

I can think of `mixin(foo())` but there is probably a nicer way 
that preserves normal function calling syntax.


Cheers,
  Johan



Re: Interfacing with C - calling member function of D struct from C?

2017-06-25 Thread unleashy via Digitalmars-d-learn

On Sunday, 25 June 2017 at 02:09:53 UTC, Adam D. Ruppe wrote:

On Sunday, 25 June 2017 at 02:05:35 UTC, unleashy wrote:

How would I call `addToBar` from C code?


You don't. Instead write it like:

struct Foo
{
int bar;
}

extern(C) void addToBar(Foo* foo, int what) {
   foo.bar += what;
}


Then define it in C the same way and you call it the normal way 
from C.


But from D, you can UFCS call it:

Foo* foo = new Foo();
foo.addToBar(5); // cool


though I'd prolly just call it from D the same way you do from 
C too.


Thank you, this is what I suspected :)


Re: Using templates with interfaces

2017-06-25 Thread Andrew Chapman via Digitalmars-d-learn
I think you've answered the question with "You cannot have 
unimplemented templates in interfaces".  Thanks for the answer.  
I'll rethink the way I'm doing this.


Cheers.


Re: Using templates with interfaces

2017-06-25 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 25 June 2017 at 13:04:32 UTC, Nicholas Wilson wrote:

On Sunday, 25 June 2017 at 11:39:27 UTC, Andrew Chapman wrote:
Hi guys, I'm a little confused as to whether D supports 
interfaces with templates.  I can compile OK, but linking 
reports an error like this:


Error 42: Symbol Undefined 
_D12relationaldb10interfaces21RÇëÜDBIÇêÿ35__T7loadRowTS6prefix÷6P¶ZÇêáMFAyaAS3std7variant18Çâ└8VÇåìNVki20ZÇëÅZÇûð


Essentially my desired interface looks like this:

interface RelationalDBInterface {
public T loadRow(T)(string sql, Variant[] params);
}

An example implementation:

public T loadRow(T)(string sql, Variant[] params)
{
Prepared prepared = prepare(this.conn, sql);
prepared.setArgs(params);

auto row = prepared.queryRow();

if (row.isNull()) {
	throw new Exception(this.classID ~ "::loadRow - Query 
returned an empty row");

}

T item;
return row.toStruct!T(item);
}

And I would try to call it like this:

auto user = this.loadRow!User(sql, params);

Is it possible, or do I need to rethink the solution?  The 
idea is to pass around a RelationalDBInterface so I can later 
switch from MySQL to Postgres or SQLite or whatever.


You cannot have unimplemented templates in interfaces (where 
would they go in the virtual function table?), just return a 
variant.

Implementations of interfaces must be classes not free functions
so

class MyDB : IRelationalDB
{
// implementation ...
}

which you then need to create a instance of

auto mydb = MyDB(...); // connection
auto user = mydb.loadRow!User(sql, params);

'this' is only valid inside an aggregate (struct or class).


Sorry I wasn't very clear.  My "this" was infact inside a class.

Here's a more complete example of attempting to use the intertace:

class MySQLRelationalDB : RelationalDBInterface {
private Connection conn;
private const string classID = "MySQLRelationalDB";

this(Connection conn) {
this.conn = conn;
}

public T loadRow(T)(string sql, Variant[] params)
{
Prepared prepared = prepare(this.conn, sql);
prepared.setArgs(params);

auto row = prepared.queryRow();

if (row.isNull()) {
throw new Exception(this.classID ~ "::loadRow - Query 
returned an empty row");

}

T item;
row.toStruct!T(item);

return item;
}
}

Then I use it within another class like this:

class UserQuery
{
protected RelationalDBInterface relationalDb;

this(RelationalDBInterface relationalDb) {
this.relationalDb = relationalDb;
}

public User getUser(string emailAddress)
{
string sql = "
SELECT *
FROM usr
WHERE email = ?
";

auto user = this.relationalDb.loadRow!User(
sql,  variantArray(emailAddress)
);
}
}

It compiles, but it wont link.  Is it the case that you can't use 
templates with interfaces?


Re: Using templates with interfaces

2017-06-25 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 25 June 2017 at 11:39:27 UTC, Andrew Chapman wrote:
Hi guys, I'm a little confused as to whether D supports 
interfaces with templates.  I can compile OK, but linking 
reports an error like this:


Error 42: Symbol Undefined 
_D12relationaldb10interfaces21RÇëÜDBIÇêÿ35__T7loadRowTS6prefix÷6P¶ZÇêáMFAyaAS3std7variant18Çâ└8VÇåìNVki20ZÇëÅZÇûð


Essentially my desired interface looks like this:

interface RelationalDBInterface {
public T loadRow(T)(string sql, Variant[] params);
}

An example implementation:

public T loadRow(T)(string sql, Variant[] params)
{
Prepared prepared = prepare(this.conn, sql);
prepared.setArgs(params);

auto row = prepared.queryRow();

if (row.isNull()) {
	throw new Exception(this.classID ~ "::loadRow - Query 
returned an empty row");

}

T item;
return row.toStruct!T(item);
}

And I would try to call it like this:

auto user = this.loadRow!User(sql, params);

Is it possible, or do I need to rethink the solution?  The idea 
is to pass around a RelationalDBInterface so I can later switch 
from MySQL to Postgres or SQLite or whatever.


You cannot have unimplemented templates in interfaces (where 
would they go in the virtual function table?), just return a 
variant.

Implementations of interfaces must be classes not free functions
so

class MyDB : IRelationalDB
{
// implementation ...
}

which you then need to create a instance of

auto mydb = MyDB(...); // connection
auto user = mydb.loadRow!User(sql, params);

'this' is only valid inside an aggregate (struct or class).




Accessing function frame from struct

2017-06-25 Thread Sebastien Alaiwan via Digitalmars-d-learn

Hi guys,
here's my full code below.
My problem is that last "auto Y = X" assignment, that the 
compiler won't accept:


yo.globalFunction.DirectStruct.IndirectStruct.indirectMemberFunc 
cannot access frame of function yo.globalFunction


I was expecting X to be accessible from here.
Suprisingly, if I replace all "struct" with "class", the last 
assignment is accepted by the compiler.
Could someone please tell me why the scoping asymmetry between 
structs and classes?


void globalFunction()
{
  auto X = 0;

  struct DirectStruct
  {
void directMemberFunc()
{
  auto Y = X; // OK, X is accessible

  struct HybridStruct
  {
void hybridFunc()
{
  auto Y = X; // OK, X is accessible
}
  }
}

struct IndirectStruct
{
  void indirectMemberFunc()
  {
auto Y = X; // Error: can't access frame of globalFunc
  }
}
  }
}




Using templates with interfaces

2017-06-25 Thread Andrew Chapman via Digitalmars-d-learn
Hi guys, I'm a little confused as to whether D supports 
interfaces with templates.  I can compile OK, but linking reports 
an error like this:


Error 42: Symbol Undefined 
_D12relationaldb10interfaces21RÇëÜDBIÇêÿ35__T7loadRowTS6prefix÷6P¶ZÇêáMFAyaAS3std7variant18Çâ└8VÇåìNVki20ZÇëÅZÇûð


Essentially my desired interface looks like this:

interface RelationalDBInterface {
public T loadRow(T)(string sql, Variant[] params);
}

An example implementation:

public T loadRow(T)(string sql, Variant[] params)
{
Prepared prepared = prepare(this.conn, sql);
prepared.setArgs(params);

auto row = prepared.queryRow();

if (row.isNull()) {
	throw new Exception(this.classID ~ "::loadRow - Query 
returned an empty row");

}

T item;
return row.toStruct!T(item);
}

And I would try to call it like this:

auto user = this.loadRow!User(sql, params);

Is it possible, or do I need to rethink the solution?  The idea 
is to pass around a RelationalDBInterface so I can later switch 
from MySQL to Postgres or SQLite or whatever.