Re: class template conflict

2018-12-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/23/18 7:09 AM, Michelle Long wrote:

class X
{

}

class X(int N) : X
{

}

Is there any real reason we can't do this?


I think it has less to do with class names and more to do with symbol 
overloading.


The only place I think templates are allowed to overload names with 
non-templates is functions, which actually was not always the case (you 
used to have to only have templates or non templates as function overloads).




It is very nice to be able to treat X like the base and X!n as a derived 
class.


The problem I see is:

template foo(alias A) { ... }

foo!X

Did you mean class X or template X?

For functions, this is OK, because it's one overload set.

-Steve


Re: class template conflict

2018-12-23 Thread Michelle Long via Digitalmars-d-learn

More simple is : do not use the same identifier ;)


The whole point is to use the same identifier ;/


Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Vijay Nayar via Digitalmars-d-learn

On Sunday, 23 December 2018 at 19:10:06 UTC, Alex wrote:

On Sunday, 23 December 2018 at 18:53:15 UTC, Vijay Nayar wrote:
You're right, it does compile. I'm a bit surprised. I wonder 
if this is a relatively recent improvement in the language, 
because last time I ran into this I had no such luck. But 
after seeing that your example did work, I figured one could 
try to get the best of both worlds by using a strongly-typed 
wrapper function in one's class.  So far it seems to work:


import std.traits;

class A(KeyT, alias HashF) {
  // Strongly-typed wrapper around template value parameter 
'HashF'.

  static size_t hash(in KeyT key) {
return HashF(key);
  }
  static this() {
static assert(isCallable!HashF, "Hash function is not 
callable!");
static assert(Parameters!(HashF).length == 1, "Hash 
function must take 1 argument.");

static assert(is(Parameters!(HashF)[0] : const(KeyT)),
"Hash parameter must be const.");
static assert(is(typeof(HashF(KeyT.init)) : size_t),
"Hash function must return size_t type.");
  }

  KeyT data;
  size_t getHash() const {
return hash(data);
  }
}

void main() {
auto a = new A!(int, (int a) => cast(size_t) a);
a.data = 5;
a.getHash();
}


I'm not sure, whether you need the static this() part at all, 
as all of the asserts the compiler should do even when they are 
absent...


by isCallable you restrict the HashF to not use IFTI
by calling HashF(key) you ensure implicitely, that 
Parameters!(HashF).length == 1
by having hash(in KeyT key) defined with an "in" you ensured, 
that HashF does not mutate the argument
and by defining size_t getHash() you ensured the return type of 
HashF...


You are correct again! Playing around with using classes and 
functions returning the wrong type or not having a const 
argument, it seems that the compiler will assure that all the 
conditions needed by the wrapper function are satisfied and give 
a clear error.


I don't know when this happened, but this definitely makes the 
language a lot easier to use for these circumstances, and all the 
std.traits stuff in "static this()" can be thrown out.


Re: Where do I learn to use GtkD

2018-12-23 Thread Ron Tarrant via Digitalmars-d-learn

On Tuesday, 30 October 2018 at 04:22:21 UTC, helxi wrote:

On Sunday, 13 March 2016 at 19:28:57 UTC, karabuta wrote:
Gtk3 from python3 has got I nice book with examples that are 
not so advanced but enough to get you doing real work(from a 
beginner point of view). GtkD seem to have changed the API 
structure compared to python3 Gtk3 and the demo examples just 
"show-off" IMO :). The documentation is really^ not good :)


Any help on where I can get better leaning materials(GtkD)? 
Repo, blogs post, etc please


Sorry for the shameless self plug, and I know it's already too 
late. I have been working on porting some of the pygtk examples 
to GtkD and covered almost the half of it. For anyone who is 
reading this thread please check out the repo I mention bellow. 
For experienced users of GtkD, please leave your PRs and 
suggestions.



https://gitlab.com/9898287/gtkdnotes


So you know your posts weren't in vain, I've been struggling with 
one of the fundamentals of signals and buttons for the last three 
days and your notes got me out of the mire. Thanks, helxi.


Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Alex via Digitalmars-d-learn

On Sunday, 23 December 2018 at 18:53:15 UTC, Vijay Nayar wrote:
You're right, it does compile. I'm a bit surprised. I wonder if 
this is a relatively recent improvement in the language, 
because last time I ran into this I had no such luck. But after 
seeing that your example did work, I figured one could try to 
get the best of both worlds by using a strongly-typed wrapper 
function in one's class.  So far it seems to work:


import std.traits;

class A(KeyT, alias HashF) {
  // Strongly-typed wrapper around template value parameter 
'HashF'.

  static size_t hash(in KeyT key) {
return HashF(key);
  }
  static this() {
static assert(isCallable!HashF, "Hash function is not 
callable!");
static assert(Parameters!(HashF).length == 1, "Hash 
function must take 1 argument.");

static assert(is(Parameters!(HashF)[0] : const(KeyT)),
"Hash parameter must be const.");
static assert(is(typeof(HashF(KeyT.init)) : size_t),
"Hash function must return size_t type.");
  }

  KeyT data;
  size_t getHash() const {
return hash(data);
  }
}

void main() {
auto a = new A!(int, (int a) => cast(size_t) a);
a.data = 5;
a.getHash();
}


I'm not sure, whether you need the static this() part at all, as 
all of the asserts the compiler should do even when they are 
absent...


by isCallable you restrict the HashF to not use IFTI
by calling HashF(key) you ensure implicitely, that 
Parameters!(HashF).length == 1
by having hash(in KeyT key) defined with an "in" you ensured, 
that HashF does not mutate the argument
and by defining size_t getHash() you ensured the return type of 
HashF...




Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Vijay Nayar via Digitalmars-d-learn

On Sunday, 23 December 2018 at 18:31:24 UTC, Alex wrote:

On Sunday, 23 December 2018 at 18:13:25 UTC, Vijay Nayar wrote:
For example, if you have a const function in your container 
like "T find() const", and this function needs to use that 
comparator, then you're out of luck because the compiler 
doesn't know that the comparator function is const and will 
not modify the objects being compared.


Last time I ran into this problem, my solution was simply to 
give up on const. But now I'm running into it again and trying 
to think through it again before giving up again.


Hm... still not sure... ;)
This would compile and run:

´´´
import std.experimental.all;

size_t myHashFunction(int a) { return cast(size_t) a; }

void main()
{
auto b = new B!(int, myHashFunction);
b.arr = 42.iota.array;
assert(b.find == 1);
}

class B(T, alias HashF)
{
T[] arr;

T find() const
{
foreach(el; arr)
{
if(HashF(el))
{
return el;
}
}
assert(0);
}
}
´´´


You're right, it does compile. I'm a bit surprised. I wonder if 
this is a relatively recent improvement in the language, because 
last time I ran into this I had no such luck. But after seeing 
that your example did work, I figured one could try to get the 
best of both worlds by using a strongly-typed wrapper function in 
one's class.  So far it seems to work:


import std.traits;

class A(KeyT, alias HashF) {
  // Strongly-typed wrapper around template value parameter 
'HashF'.

  static size_t hash(in KeyT key) {
return HashF(key);
  }
  static this() {
static assert(isCallable!HashF, "Hash function is not 
callable!");
static assert(Parameters!(HashF).length == 1, "Hash function 
must take 1 argument.");

static assert(is(Parameters!(HashF)[0] : const(KeyT)),
"Hash parameter must be const.");
static assert(is(typeof(HashF(KeyT.init)) : size_t),
"Hash function must return size_t type.");
  }

  KeyT data;
  size_t getHash() const {
return hash(data);
  }
}

void main() {
auto a = new A!(int, (int a) => cast(size_t) a);
a.data = 5;
a.getHash();
}


Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Alex via Digitalmars-d-learn

On Sunday, 23 December 2018 at 18:13:25 UTC, Vijay Nayar wrote:
I've been playing with the idea of specifying the constraints 
or using "static assert" in the constructor. They are good 
options, but there's a few cases where they fall a bit short.  
For example, imagine you have a container class that needs a 
comparator function to be able to compare the items in the 
container.  While you can use std.traits to assure the right 
kind of function is passed in, that information does not make 
its way into the type system.


For example, if you have a const function in your container 
like "T find() const", and this function needs to use that 
comparator, then you're out of luck because the compiler 
doesn't know that the comparator function is const and will not 
modify the objects being compared.


Last time I ran into this problem, my solution was simply to 
give up on const. But now I'm running into it again and trying 
to think through it again before giving up again.


Hm... still not sure... ;)
This would compile and run:

´´´
import std.experimental.all;

size_t myHashFunction(int a) { return cast(size_t) a; }

void main()
{
auto b = new B!(int, myHashFunction);
b.arr = 42.iota.array;
assert(b.find == 1);
}

class B(T, alias HashF)
{
T[] arr;

T find() const
{
foreach(el; arr)
{
if(HashF(el))
{
return el;
}
}
assert(0);
}
}
´´´


Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Vijay Nayar via Digitalmars-d-learn

On Sunday, 23 December 2018 at 18:04:32 UTC, Alex wrote:

On Sunday, 23 December 2018 at 17:13:49 UTC, Vijay Nayar wrote:
I have a few cases where I would like to pass in a function as 
a value to a template, but I want to ensure that the function 
takes certain kinds of parameters, is a const function, or 
matches any other set of conditions.


I assume you are looking for constraints...
https://dlang.org/concepts.html

Then, case B is the way to go, see
https://run.dlang.io/is/jWU3tr

Case D also looks promising. Not sure, how to formulate the 
specialization right now...


There are a lot of traits you can use for the constraints.
https://dlang.org/phobos/std_traits.html
and
https://dlang.org/spec/traits.html
e.g., for constness there is getFunctionAttributes, which could 
be useful.


I've been playing with the idea of specifying the constraints or 
using "static assert" in the constructor. They are good options, 
but there's a few cases where they fall a bit short.  For 
example, imagine you have a container class that needs a 
comparator function to be able to compare the items in the 
container.  While you can use std.traits to assure the right kind 
of function is passed in, that information does not make its way 
into the type system.


For example, if you have a const function in your container like 
"T find() const", and this function needs to use that comparator, 
then you're out of luck because the compiler doesn't know that 
the comparator function is const and will not modify the objects 
being compared.


Last time I ran into this problem, my solution was simply to give 
up on const. But now I'm running into it again and trying to 
think through it again before giving up again.


Re: Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Alex via Digitalmars-d-learn

On Sunday, 23 December 2018 at 17:13:49 UTC, Vijay Nayar wrote:
I have a few cases where I would like to pass in a function as 
a value to a template, but I want to ensure that the function 
takes certain kinds of parameters, is a const function, or 
matches any other set of conditions.


What is the best way to do this? Just to avoid any potential 
confusion, I've included a few examples below. I'm using 
explicit functions rather than lambdas just avoid any 
possibility of types being incorrectly inferred.


size_t myHashFunction(int a) { return cast(size_t) a; }

void main() {
class A(KeyT, HashF) { }
auto a = new A!(int, myHashFunction);
// ^ onlineapp.d: Error: template instance `A!(int, 
myHashFunction)`

// does not match template declaration `A(KeyT, HashF)`

// Alias parameter: 
https://dlang.org/spec/template.html#aliasparameters

class B(KeyT, alias HashF) { }
auto b = new B!(int, myHashFunction);
// ^ Works, but we cannot enforce the kind of function 
passed in.


// Typed alias parameter: 
https://dlang.org/spec/template.html#typed_alias_op

class C(KeyT, alias size_t function(KeyT) HashF) { }
auto c = new C!(int, myHashFunction);
// ^ onlineapp.d: Error: template instance `C!(int, 
myHashFunction)`
// does not match template declaration `C(KeyT, alias 
size_t function(KeyT) HashF)`


// Specialization: 
https://dlang.org/spec/template.html#alias_parameter_specialization

class D(KeyT, alias HashF : size_t function(KeyT)) { }
auto d = new D!(int, myHashFunction
// ^ onlineapp.d: Error: template instance `D!(int, 
myHashFunction)`
// does not match template declaration `D(KeyT, alias HashF 
: size_t function(KeyT))`

}

Looking at some of the code in std.algorithm, it seem that 
static asserts are sometimes used for this purpose. Does anyone 
have a solution to this problem of instantiating template 
classes whose parameters are functions?  I have used 
std.function "unaryFun" before, but this has the problem of not 
being able to specify function attributes, like const.


I assume you are looking for constraints...
https://dlang.org/concepts.html

Then, case B is the way to go, see
https://run.dlang.io/is/jWU3tr

Case D also looks promising. Not sure, how to formulate the 
specialization right now...


There are a lot of traits you can use for the constraints.
https://dlang.org/phobos/std_traits.html
and
https://dlang.org/spec/traits.html
e.g., for constness there is getFunctionAttributes, which could 
be useful.


Best Way to Pass Template Typed Alias Parameters for Functions?

2018-12-23 Thread Vijay Nayar via Digitalmars-d-learn
I have a few cases where I would like to pass in a function as a 
value to a template, but I want to ensure that the function takes 
certain kinds of parameters, is a const function, or matches any 
other set of conditions.


What is the best way to do this? Just to avoid any potential 
confusion, I've included a few examples below. I'm using explicit 
functions rather than lambdas just avoid any possibility of types 
being incorrectly inferred.


size_t myHashFunction(int a) { return cast(size_t) a; }

void main() {
class A(KeyT, HashF) { }
auto a = new A!(int, myHashFunction);
// ^ onlineapp.d: Error: template instance `A!(int, 
myHashFunction)`

// does not match template declaration `A(KeyT, HashF)`

// Alias parameter: 
https://dlang.org/spec/template.html#aliasparameters

class B(KeyT, alias HashF) { }
auto b = new B!(int, myHashFunction);
// ^ Works, but we cannot enforce the kind of function passed 
in.


// Typed alias parameter: 
https://dlang.org/spec/template.html#typed_alias_op

class C(KeyT, alias size_t function(KeyT) HashF) { }
auto c = new C!(int, myHashFunction);
// ^ onlineapp.d: Error: template instance `C!(int, 
myHashFunction)`
// does not match template declaration `C(KeyT, alias size_t 
function(KeyT) HashF)`


// Specialization: 
https://dlang.org/spec/template.html#alias_parameter_specialization

class D(KeyT, alias HashF : size_t function(KeyT)) { }
auto d = new D!(int, myHashFunction
// ^ onlineapp.d: Error: template instance `D!(int, 
myHashFunction)`
// does not match template declaration `D(KeyT, alias HashF : 
size_t function(KeyT))`

}

Looking at some of the code in std.algorithm, it seem that static 
asserts are sometimes used for this purpose. Does anyone have a 
solution to this problem of instantiating template classes whose 
parameters are functions?  I have used std.function "unaryFun" 
before, but this has the problem of not being able to specify 
function attributes, like const.


Re: class template conflict

2018-12-23 Thread Basile B. via Digitalmars-d-learn

On Sunday, 23 December 2018 at 12:09:31 UTC, Michelle Long wrote:

class X
{

}

class X(int N) : X
{

}

Is there any real reason we can't do this?

It is very nice to be able to treat X like the base and X!n as 
a derived class.


Sure we can do

class X(int N) : X!0
{
   static if(N == 0)
   {
   }
}

but this is very ugly, in my code I always have to use X!0 as 
the basis!


I do not think there is any harm to allow this since the 
templated class always has to specify N. It is not like we can 
do


class X(int N = 0) : X
{
   static if(N == 0)
   {
   }
}


Actually we can, so... I don't see the point in not allowing 
the first case, they are logically equivalent. That static if 
is just ugly and it is defining the base class inside the 
derived class which seems unnatural.


You have this option too:

```
template X(N...)
if (N.length == 0 ||
N.length == 1 && is(typeof(N[0]) == int))
{
static if (N.length == 0)
class X {}

else class X : X!() {}
}

auto base = new X!();
auto derived = new X!8;
```

More simple is : do not use the same identifier ;)


cas and interfaces

2018-12-23 Thread Johannes Loher via Digitalmars-d-learn
I recently played around with atomic operations. While doing so, 
I noticed a problem with the interaction of interfaces and cas. 
Consider the following program:


```
import core.atomic;
import std.stdio;

interface TestInterface
{
}

class TestClass : TestInterface
{
}

void main()
{
shared TestInterface testInterface = new shared TestClass;
cas(, testInterface, new shared 
TestClass).writeln;

writeln(typeid(testInterface));
}
```
(https://run.dlang.io/is/9P7PAb)

This program compiles successfully and outputs

```
true
Error: program killed by signal 11
```

i.e. a segmentation fault happens.

When replacing "interface" with "abstract class" 
(https://run.dlang.io/is/sFaO1k), everything works as expected 
and the program outputs


```
true
onlineapp.TestClass
```

Is this actually a bug or a fundamental limitation of cas and 
interfaces? Did I do anything wrong?


class template conflict

2018-12-23 Thread Michelle Long via Digitalmars-d-learn

class X
{

}

class X(int N) : X
{

}

Is there any real reason we can't do this?

It is very nice to be able to treat X like the base and X!n as a 
derived class.


Sure we can do

class X(int N) : X!0
{
   static if(N == 0)
   {
   }
}

but this is very ugly, in my code I always have to use X!0 as the 
basis!


I do not think there is any harm to allow this since the 
templated class always has to specify N. It is not like we can do


class X(int N = 0) : X
{
   static if(N == 0)
   {
   }
}


Actually we can, so... I don't see the point in not allowing the 
first case, they are logically equivalent. That static if is just 
ugly and it is defining the base class inside the derived class 
which seems unnatural.