Re: How to Instantiate struct defined in template

2012-09-22 Thread Craig Dillabaugh

On Sunday, 23 September 2012 at 04:51:31 UTC, Jonathan M Davis
wrote:

On Sunday, September 23, 2012 06:37:30 Craig Dillabaugh wrote:

One question. Is there any way to get the function template to
deduce the type of T from the vertices I pass, so that I can
call:

euclid_dist(v1, v2) )

instead of:

euclid_dist!float(v1, v2) );


It should infer the types just fine as-is. Templated functions 
can pretty much
always infer the template arguments from their function 
arguments. It's with
types that that doesn't work (so a constructor requires 
template arguments,

but a function does not).

- Jonathan M Davis


Yes, you are right. I thought I had tried it without the !float
and it hadn't worked, but I guess not.

Thanks again for all your help.
Craig


Re: How to Instantiate struct defined in template

2012-09-22 Thread Jonathan M Davis
On Sunday, September 23, 2012 06:37:30 Craig Dillabaugh wrote:
> One question. Is there any way to get the function template to
> deduce the type of T from the vertices I pass, so that I can
> call:
> 
> euclid_dist(v1, v2) )
> 
> instead of:
> 
> euclid_dist!float(v1, v2) );

It should infer the types just fine as-is. Templated functions can pretty much 
always infer the template arguments from their function arguments. It's with 
types that that doesn't work (so a constructor requires template arguments, 
but a function does not).

- Jonathan M Davis


Re: How to Instantiate struct defined in template

2012-09-22 Thread Craig Dillabaugh

On Sunday, 23 September 2012 at 04:03:28 UTC, Jonathan M Davis
wrote:

On Sunday, September 23, 2012 05:49:06 Craig Dillabaugh wrote:

Hello,


clip



Before anything, I'd question why you declared vt at all. If 
all you're
putting in it is a single struct, then just templatize the 
struct directly:


struct Vertex(T)
{
...
}

Now, it looks like you have a free function in there as well - 
euclid_dist -
but there's no reason to put that in the same template. Just 
templatize it

directly. Then you get

T euclid_dist(T)(T a, T b) {...}

And main ends up looking something like

void main()
{
auto v1 = Vertex!float(0.0, 0.0);
auto v2 = Vertex!float(2.0, 4.0);
writefln("The distance between vertex 1 and vertex 2 is %s",
 euclid_dist(v1, v2));
}

Thanks. I've switched my code to follow your suggestion. One thing
there was a typo in my euclid_dist function, the code for it, and
main now look like:

T euclid_dist(T)(vertex!T a, vertex!T b) {
T sum = 0;
foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords ) ) {
sum += (a_crd - b_crd)*(a_crd - b_crd );
}
return sqrt(sum);
}

int main(string argv[] ) {
auto v1 = vertex!float(0.0,0.0);
auto v2 = vertex!float(3.0,4.0);
writeln("The distance between vertex 1 and vertex 2 is ",
euclid_dist!float(v1, v2) );
return 0;
}

One question. Is there any way to get the function template to
deduce the type of T from the vertices I pass, so that I can
call:

euclid_dist(v1, v2) )

instead of:

euclid_dist!float(v1, v2) );



It's actually fairly to explicitly declare a template in D 
outside of
eponymous templates. If you're dealing with a user-defined type 
or function, it

almost always makes more sense to templatize them directly.

Now, as for the exact error message, it's because the syntax 
that you're using

to define v1 and v2 is illegal. You'd need to do either

vt!float.vertex v1 = vt!float(0.0, 0.0);

or preferrably.

auto v1 = vt!float(0.0, 0.0);

You can't construct the type on the left-hand side of the 
assignment operator

like that.

- Jonathan M Davis


,



Re: How to Instantiate struct defined in template

2012-09-22 Thread Jonathan M Davis
On Sunday, September 23, 2012 05:49:06 Craig Dillabaugh wrote:
> Hello,
> I am trying to figure out how templates work and tried to define
> the
> following template to define vertices of any dimension and
> operations
> on them.
> 
> import std.stdio;
> import std.random;
> import std.range;
> import std.conv;
> import std.math;
> 
> /*
>* T must be one of the floating point types
>*   float, double, real _ I should be enforcing this.
>*/
> template  vt(T)
> {
> struct vertex {
>   this(T[] crds...) {
> if( crds.length < 2 ) {
>   throw new.Exception("To small!");
> } else {
>   coords.length = crds.length;
>   foreach(ref v_coord, in_coord; lockstep(coords, crds))
>   {
> v_coord = in_coord;
>   }
> }
>   }
>   @property T x() { return coords[0];}
>   @property T y() { return coords[1];}
>   @property T z() { return ( coords.length < 3 ? T.nan :
> coords[2] ); }
> }
> 
> T euclid_dist(T a, T b) {
>   T sum = 0;
>   foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords )
> ) {
> sum += (a_crd - b_crd)*(a_crd - b_crd );
>   }
>   return sqrt(sum);
> }
> } //End of template
> 
> int main(string argv[] ) {
>   vt!(float).vertex v1(0.0,0.0);
>   vt!(float).vertex v2(3.0,4.0);
>   writefln("The distance between vertex 1 and vertex 2 is ",
>   vt!(float).euclid_dist(v1, v2) );
> }
> 
> When I try to compile this I get the message:
> 
> vertex.d(57): Error: found 'v1' when expecting ';' following
> statement
> vertex.d(58): Error: found 'v2' when expecting ';' following
> statement
> 
> Lines 57 and 58 are the first two lines in my main() function. I
> can't figure out why, from the examples I've looked at I am using
> the syntax properly, but am clearly missing something.
> 
> Also, since I don't really know what I am doing any criticisms on
> how I am defining the vertex template are welcome.

Before anything, I'd question why you declared vt at all. If all you're 
putting in it is a single struct, then just templatize the struct directly:

struct Vertex(T)
{
...
}

Now, it looks like you have a free function in there as well - euclid_dist - 
but there's no reason to put that in the same template. Just templatize it 
directly. Then you get

T euclid_dist(T)(T a, T b) {...}

And main ends up looking something like

void main()
{
auto v1 = Vertex!float(0.0, 0.0);
auto v2 = Vertex!float(2.0, 4.0);
writefln("The distance between vertex 1 and vertex 2 is %s",
 euclid_dist(v1, v2));
}

It's actually fairly to explicitly declare a template in D outside of 
eponymous templates. If you're dealing with a user-defined type or function, it 
almost always makes more sense to templatize them directly.

Now, as for the exact error message, it's because the syntax that you're using 
to define v1 and v2 is illegal. You'd need to do either

vt!float.vertex v1 = vt!float(0.0, 0.0);

or preferrably.

auto v1 = vt!float(0.0, 0.0);

You can't construct the type on the left-hand side of the assignment operator 
like that.

- Jonathan M Davis


How to Instantiate struct defined in template

2012-09-22 Thread Craig Dillabaugh

Hello,
I am trying to figure out how templates work and tried to define
the
following template to define vertices of any dimension and
operations
on them.

import std.stdio;
import std.random;
import std.range;
import std.conv;
import std.math;

/*
  * T must be one of the floating point types
  *   float, double, real _ I should be enforcing this.
  */
template  vt(T)
{
   struct vertex {
 this(T[] crds...) {
   if( crds.length < 2 ) {
 throw new.Exception("To small!");
   } else {
coords.length = crds.length;
foreach(ref v_coord, in_coord; lockstep(coords, crds))
{
  v_coord = in_coord;
}
   }
 }
 @property T x() { return coords[0];}
 @property T y() { return coords[1];}
 @property T z() { return ( coords.length < 3 ? T.nan :
coords[2] ); }
   }

   T euclid_dist(T a, T b) {
 T sum = 0;
 foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords )
) {
   sum += (a_crd - b_crd)*(a_crd - b_crd );
 }
 return sqrt(sum);
   }
} //End of template

int main(string argv[] ) {
vt!(float).vertex v1(0.0,0.0);
vt!(float).vertex v2(3.0,4.0);
writefln("The distance between vertex 1 and vertex 2 is ",
vt!(float).euclid_dist(v1, v2) );
}

When I try to compile this I get the message:

vertex.d(57): Error: found 'v1' when expecting ';' following
statement
vertex.d(58): Error: found 'v2' when expecting ';' following
statement

Lines 57 and 58 are the first two lines in my main() function. I
can't figure out why, from the examples I've looked at I am using
the syntax properly, but am clearly missing something.

Also, since I don't really know what I am doing any criticisms on
how I am defining the vertex template are welcome.

Cheers,

Craig


Re: Testing for template argument being result of takeExactly

2012-09-22 Thread Jonathan M Davis
On Sunday, September 23, 2012 02:57:36 bearophile wrote:
> Jonathan M Davis:
> > So, clearly I don't have the is expression right, and this is
> > seriously pushing the edge of my knowledge of is expressions.
> > So, any help would be appreciated. Thanks.
> 
> I have done some tries, but I have failed, I am sorry :-)
> The is() syntax is a part of D good to burn on a campfire.

The power that it provides is useful if not outright necessary, but it could 
definitely use some improvements in the usability camp once you go beyond the 
basics. But I don't even know how you'd go about designing it so that it was 
more user friendly.

> But takeExactly returns a Result struct defined inside it, so it
> even possible for the is() syntax to work on this inner (hidden?)
> type? Generally the idea of defining structs inside looks nice,
> but seems a source for troubles.

Yeah. Increasingly, it looks like Voldemort types are a bad idea as nice as 
they are in principle. But we have yet to reach the point where it's clear 
that we need to ditch them. We may yet get there though.

- Jonathan M Davis


Re: Testing for template argument being result of takeExactly

2012-09-22 Thread bearophile

Jonathan M Davis:

So, clearly I don't have the is expression right, and this is 
seriously pushing the edge of my knowledge of is expressions.

So, any help would be appreciated. Thanks.


I have done some tries, but I have failed, I am sorry :-)
The is() syntax is a part of D good to burn on a campfire.
But takeExactly returns a Result struct defined inside it, so it 
even possible for the is() syntax to work on this inner (hidden?) 
type? Generally the idea of defining structs inside looks nice, 
but seems a source for troubles.


Bye,
bearophile


Testing for template argument being result of takeExactly

2012-09-22 Thread Jonathan M Davis
I'm trying to test whether a template argument is the type returned by 
takeExactly, and I haven't been able to sort out the template voodoo required 
yet. It would be a lot easier if I had a variable to work with, but I just 
have the type, and the fancy is expression required to pull it off is fancy 
enough that I haven't been able to sort it out yet. At present, I have this:

import std.range;
import std.stdio;

template Hello(R)
if(is(R r == U, V, V w, U = typeof(takeExactly(w, 1
{
alias R Hello;
}

void main()
{
auto str = "hello";
auto t = takeExactly(str, 3);
writeln(t);
Hello!(typeof(t)) h = t;
writeln(h);
}


I need Hello to instatiate if R is the type returned by takeExactly and fail 
to instantiate otherwise. At present, the code gives these compilation errors:

q.d(15): Error: template instance Hello!(Result) Hello!(Result) does not match 
template declaration Hello(R) if (is(R r == U,V,V w,U = 
typeof(takeExactly(w,1
q.d(15): Error: Hello!(Result) is used as a type
q.d(16): Error: template std.stdio.writeln does not match any function 
template declaration
q.d(16): Error: template std.stdio.writeln(T...) cannot deduce template 
function from argument types !()(_error_)

So, clearly I don't have the is expression right, and this is seriously 
pushing the edge of my knowledge of is expressions. So, any help would be 
appreciated. Thanks.

- Jonathan M Davis


Re: system vs. execvp ?

2012-09-22 Thread Peter Sommerfeld

Jonathan M Davis wrote:

Peter Sommerfeld wrote:


This works as expected:

   string cmd = "dmd src/xyz.d";
   int i = system(cmd);

But this not:

   string[] cmd;
   cmd ~= "src/xyz.d";
   int i = execvp("dmd",cmd);

Of course, dmd is in PATH (Win7).

What is wrong here?


Please elaborate on what doesn't work as expected. We can'thelp you if   
you don't tell us what's wrong.


Well, system(cmd) compiles xyz.d and creates an executable.

execvp(cmd) does call dmd but that behaves as if no arguments
where given (Usage msg etc). No executables are created.

system should run your command in a new process and return,whereas   
execvp will run it and never return, because the

new process replaces your  current one.


I did not know that it does not return. Anyway, it should
compile the args IMHO but it does not.

Peter


Re: system vs. execvp ?

2012-09-22 Thread Andrej Mitrovic
On 9/23/12, Jonathan M Davis  wrote:
> I'd be very surprised if you were correct about this.

I was wrong, it's for a different reason:
http://stackoverflow.com/questions/3027320/why-first-arg-to-execve-must-be-path-to-executable


Re: system vs. execvp ?

2012-09-22 Thread Jonathan M Davis
On Saturday, September 22, 2012 16:10:11 Jonathan M Davis wrote:
> Now, looking at the docs for std.process.execvp, they seem to think that the
> exec functions are going to return, but that's not what the man pages for
> the C functions (which they're calling) say, nor is it how they behave.

The problem with the documentation has been reported:

http://d.puremagic.com/issues/show_bug.cgi?id=8708

- Jonathan M Davis


Re: system vs. execvp ?

2012-09-22 Thread Jonathan M Davis
On Sunday, September 23, 2012 01:12:34 Andrej Mitrovic wrote:
> On 9/23/12, Peter Sommerfeld  wrote:
> > What is wrong here?
> 
>   string[] cmd;
>   cmd ~= "dmd";
>   cmd ~= "src/xyz.d";
>   int i = execvp("dmd",cmd);
> 
> 1st arg should always be the app name, even though apps typically
> ignore/skip the first arg.

Are you sure about that? That seems pretty messed up if that's the case. Yes, 
the first element in the argument list that main gets is the name of the 
program, but it's pretty messed up if any of the exec* functions require that 
you give the program name as the first argument rather than it being 
appropriately added by that program before its main is called. I'd be very 
surprised if you were correct about this.

- Jonathan M Davis


Re: system vs. execvp ?

2012-09-22 Thread Andrej Mitrovic
On 9/23/12, Peter Sommerfeld  wrote:
> What is wrong here?

  string[] cmd;
  cmd ~= "dmd";
  cmd ~= "src/xyz.d";
  int i = execvp("dmd",cmd);

1st arg should always be the app name, even though apps typically
ignore/skip the first arg.


Re: system vs. execvp ?

2012-09-22 Thread Jonathan M Davis
On Sunday, September 23, 2012 00:53:48 Peter Sommerfeld wrote:
>   Hi!
> 
> This works as expected:
> 
>string cmd = "dmd src/xyz.d";
>int i = system(cmd);
> 
> But this not:
> 
>string[] cmd;
>cmd ~= "src/xyz.d";
>int i = execvp("dmd",cmd);
> 
> Of course, dmd is in PATH (Win7).
> 
> What is wrong here?

Please elaborate on what doesn't work as expected. We can't help you if you 
don't tell us what's wrong.

system should run your command in a new process and return, whereas execvp 
will run it and never return, because the new process replaces your current 
one.

Now, looking at the docs for std.process.execvp, they seem to think that the 
exec functions are going to return, but that's not what the man pages for the 
C functions (which they're calling) say, nor is it how they behave. Maybe 
that's your problem?

http://linux.die.net/man/3/exec
http://msdn.microsoft.com/en-us/library/3xw6zy53.aspx

- Jonathan M Davis


system vs. execvp ?

2012-09-22 Thread Peter Sommerfeld

 Hi!

This works as expected:

  string cmd = "dmd src/xyz.d";
  int i = system(cmd);

But this not:

  string[] cmd;
  cmd ~= "src/xyz.d";
  int i = execvp("dmd",cmd);

Of course, dmd is in PATH (Win7).

What is wrong here?

tia Peter


Re: object.error: Privileged Instruction

2012-09-22 Thread Ali Çehreli

On 09/22/2012 11:33 AM, simendsjo wrote:

> assert(false, "aoeu"); // with message, object.error: Privileged

Yep, Dvorak keyboard rules! ;)

Ali



Re: object.error: Privileged Instruction

2012-09-22 Thread Jonathan M Davis
On Saturday, September 22, 2012 21:19:27 Maxim Fomin wrote:
> Privilege instruction is an assembly instruction which can be
> executed only at a certain executive process context, typically
> os kernel. AFAIK assert(false) was claimed to be implemented by
> dmd as a halt instruction, which is privileged one.
> 
> However, compiled code shows that dmd generates int 3 instruction
> for assert(false) statement and 61_6F_65_75 which is binary
> representation of "aoeu" for assert(false, "aoeu") statement and
> the latter is interpreted as privileged i/o instruction.

It's a normal assertion without -release. With -release, it's a halt 
instruction on Linux but IIRC it's something slightly different (albeit 
similar) on Windows, though it might be halt there too.

- Jonathan M Davis


Re: object.error: Privileged Instruction

2012-09-22 Thread Maxim Fomin
Privilege instruction is an assembly instruction which can be 
executed only at a certain executive process context, typically 
os kernel. AFAIK assert(false) was claimed to be implemented by 
dmd as a halt instruction, which is privileged one.


However, compiled code shows that dmd generates int 3 instruction 
for assert(false) statement and 61_6F_65_75 which is binary 
representation of "aoeu" for assert(false, "aoeu") statement and 
the latter is interpreted as privileged i/o instruction.


object.error: Privileged Instruction

2012-09-22 Thread simendsjo

What does the message in the subject mean?

Here's a testcase (tested on dmd 2.060 on win7 32-bit):

import core.exception;
import core.runtime; // comment out this, and no stacktrace is 
printed


void myAssertHandler(string file, size_t line, string msg = null) 
{ }


static this() {
setAssertHandler(&myAssertHandler);
f();
}

version(unittest) {
void f() {
//assert(false); // without message, object.error: 
Breakpoint
assert(false, "aoeu"); // with message, object.error: 
Privileged Instruction

}
}



Re: Passing associative array to another thread

2012-09-22 Thread Martin Drasar
On 22.9.2012 13:50, Johannes Pfau wrote:
>> 1. Declare it as "shared"
> There's also __gshared.

Yup, that works.

Thanks


Re: Passing associative array to another thread

2012-09-22 Thread Johannes Pfau
Am Sat, 22 Sep 2012 12:30:30 +0200
schrieb Jacob Carlborg :

> On 2012-09-22 11:24, Martin Drasar wrote:
> 
> > thanks for the hint. Making it shared sounds a bit fishy to me. My
> > intention is to pass some read only data, that are in fact thread
> > local and there is no real need to make them shared.
> 
> The whole point of thread local data is that it's only accessible
> from a single thread. If you want to share it with another thread you
> have, as far as I know, there options:
> 
> 1. Declare it as "shared"
There's also __gshared.

> 2. Declare it as "immutable"
> 3. Make a copy, i.e. serialize the data



Re: Passing associative array to another thread

2012-09-22 Thread Martin Drasar
On 22.9.2012 13:19, Jonathan M Davis wrote:
> The problem with immutable is probably due to this bug:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=5538
> 
> And casting to shared probably won't work due to this bug:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=6585
> 
> std.variant needs quite a bit of work done to it, and it's causing problems 
> with std.concurrency is this case. In the interim, I suspect that just about 
> the only way to get an AA across threads is to just make it shared and not 
> use 
> std.concurrency at all, as undesirable as that may be. Your serialization 
> suggestion would probably be the only other choice, though that would require 
> something like Orange, as Phobos doesn't have such facilities.
> 
> - Jonathan M Davis

Hi Jonathan,

I will work around the AA. As I have said, it is used only to pass
name-value pairs. So no need to ditch the entire std.concurrency because
of that.

Martin


Re: Passing associative array to another thread

2012-09-22 Thread Jonathan M Davis
On Saturday, September 22, 2012 12:30:30 Jacob Carlborg wrote:
> Looking at your original example I don't understand why the immutable aa
> won't work. That's the whole point of immutable, it's safe to share
> among threads. It's probably a bug somewhere. I think someone else can
> answer these questions better than me.

The problem with immutable is probably due to this bug:

http://d.puremagic.com/issues/show_bug.cgi?id=5538

And casting to shared probably won't work due to this bug:

http://d.puremagic.com/issues/show_bug.cgi?id=6585

std.variant needs quite a bit of work done to it, and it's causing problems 
with std.concurrency is this case. In the interim, I suspect that just about 
the only way to get an AA across threads is to just make it shared and not use 
std.concurrency at all, as undesirable as that may be. Your serialization 
suggestion would probably be the only other choice, though that would require 
something like Orange, as Phobos doesn't have such facilities.

- Jonathan M Davis


Re: Passing associative array to another thread

2012-09-22 Thread Jacob Carlborg

On 2012-09-22 11:24, Martin Drasar wrote:


thanks for the hint. Making it shared sounds a bit fishy to me. My
intention is to pass some read only data, that are in fact thread local
and there is no real need to make them shared.


The whole point of thread local data is that it's only accessible from a 
single thread. If you want to share it with another thread you have, as 
far as I know, there options:


1. Declare it as "shared"
2. Declare it as "immutable"
3. Make a copy, i.e. serialize the data


The (de)serialization is possible but the overhead seems a bit
pointless. I will alter the code to use something else than AAs if there
is no other way.

The data I am trying to pass is in fact just name-value pairs. I have
tried to use Tuples, but I have hit another batch of problems. One was
related to issue #5783, but another made me really scratch my head...


Looking at your original example I don't understand why the immutable aa 
won't work. That's the whole point of immutable, it's safe to share 
among threads. It's probably a bug somewhere. I think someone else can 
answer these questions better than me.


--
/Jacob Carlborg


Re: Passing associative array to another thread

2012-09-22 Thread Martin Drasar
On 21.9.2012 19:01, Jacob Carlborg wrote:
> Perhaps declaring the associative array as "shared". An alternative
> would be to serialize the aa, pass it to another thread, and deserialize
> it. That would though create a copy.

Hi Jacob,

thanks for the hint. Making it shared sounds a bit fishy to me. My
intention is to pass some read only data, that are in fact thread local
and there is no real need to make them shared.

The (de)serialization is possible but the overhead seems a bit
pointless. I will alter the code to use something else than AAs if there
is no other way.

The data I am trying to pass is in fact just name-value pairs. I have
tried to use Tuples, but I have hit another batch of problems. One was
related to issue #5783, but another made me really scratch my head...

This compiles ok:
struct S { Tuple!int i; }

This does not:
struct S {
  Tuple!int i;
  SysTime   t;
}

Error: function
std.typecons.Tuple!(int).Tuple.opEquals!(const(Tuple!(int))).opEquals
(const(Tuple!(int)) rhs) is not callable using argument types
(const(Tuple!(int))) const

This looks a lot like the #5783, but I don't understand, why it only
shows up with the SysTime in place...

Martin


Re: how is this considered hiding methods?

2012-09-22 Thread Andrej Mitrovic
On 9/22/12, Andrej Mitrovic  wrote:
> I would prefer if "super.alias" meant to take overloads of all base
> classes into account.

Although this would be kind of counter-intuitive since 'super' already
means the direct base class.


Re: how is this considered hiding methods?

2012-09-22 Thread Andrej Mitrovic
On 9/22/12, Andrej Mitrovic  wrote:
> Now let's say the Doo clas removes the meth overload and the alias:

Sorry that should be "the Bar class".


Re: how is this considered hiding methods?

2012-09-22 Thread Andrej Mitrovic
On 9/22/12, Andrej Mitrovic  wrote:
> using the alias

But I do think this can be further improved in the language. Take this
for example:

import std.stdio;

class Foo
{
void meth(double) { writeln("Foo.meth"); }
}

class Bar : Foo
{
alias super.meth meth;
void meth(int) { writeln("Bar.meth"); }
}

class Doo : Bar
{
alias super.meth meth;
void meth(long) { writeln("Doo.meth"); }
}

void main()
{
auto doo = new Doo;
doo.meth(1);  // calls Bar.meth
}

Now let's say the Doo clas removes the meth overload and the alias:

class Foo
{
void meth(double) { writeln("Foo.meth"); }
}

class Bar : Foo
{
// gone
}

class Doo : Bar
{
alias super.meth meth;
void meth(long) { writeln("Doo.meth"); }
}

void main()
{
auto doo = new Doo;
doo.meth(1);   // now calls Doo.meth
}

We might have wanted the "super alias" in Doo to only work against the
Bar base class so the compiler can notify us if Doo.meth is removed.
The language doesn't have a way to warn us of this.

I would prefer if "super.alias" meant to take overloads of all base
classes into account and that we could use "ClassName.alias" to only
import the overload set of a specific base class. That way this would
trigger a CT error:

class Foo
{
void meth(double) { writeln("Foo.meth"); }
}

class Bar : Foo
{
}

class Doo : Bar
{
alias Bar.meth meth;  // error: no overload set in Bar
void meth(long) { writeln("Doo.meth"); }
}


Re: how is this considered hiding methods?

2012-09-22 Thread Andrej Mitrovic
On 9/22/12, Jonathan M Davis  wrote:
> But why the compiler would now require that you do that, I
> don't know. If that's the way that thnigs currently are, it starts to become
> a bit odd that the base class functions aren't automatically available.

http://dlang.org/hijack.html

There's a good reason why, consider:

class Foo
{
void foo(int) { }
}

class Bar : Foo
{
alias super.foo foo;
void foo(double) { }
}

void main()
{
auto bar = new Bar;
bar.foo(1);  // calls Foo.foo
}

Now let's say Foo is a library class and you upgrade to a new version
of the library without realizing that the base method was removed:

class Foo
{
}

class Bar : Foo
{
alias super.foo foo;   // error
void foo(double) { }
}

This now becomes a compile-time error. Without using the alias which
triggers the error the literal "1" would be implicitly converted to a
double and you'd end up invoking your own 'foo' method (which is no
longer an overload).


Re: how is this considered hiding methods?

2012-09-22 Thread Jonathan M Davis
On Saturday, September 22, 2012 09:49:04 Gor Gyolchanyan wrote:
> Can someone please tell me why the following code gives these
> errors?
> 
> Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal
> animal_) hidden by BirdZoo is deprecated
> 
> Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal
> animal_) hidden by ParrotZoo is deprecated
> 
> /// The code:
> 
>   class Animal { }
>   class Vertebrate { }
>   class Bird: Animal { }
>   class Parrot: Bird { }
> 
>   class VertebrateZoo
>   {
>   void take(Animal animal_)
>   {
>   if(auto vertebrate = cast(Vertebrate)animal_)
>   take(vertebrate);
>   }
> 
>   abstract void take(Vertebrate vertebrate_);
>   }
> 
>   class BirdZoo: VertebrateZoo
>   {
>   override void take(Vertebrate vertebrate_)
>   {
>   if(auto bird = cast(Bird)vertebrate_)
>   take(bird);
>   }
> 
>   abstract void take(Bird bird_);
>   }
> 
>   class ParrotZoo: BirdZoo
>   {
>   override void take(Bird bird_)
>   {
>   if(auto parrot = cast(Parrot)bird_)
>   take(parrot);
>   }
> 
>   abstract void take(Parrot parrot_);
>   }

The problem goes away if you add

alias VertebrateZoo.take take;

It also goes away if you change take in the derived class to take Animal.

My guess is that the problem is that the version of take which takes an Animal 
is unavailable in the derived classes and is therefore "hidden." Any time that 
you add an overload to a derived class which does not exactly override a 
function in the base class, the base class overload is hidden in the derived 
class. The normal fix for this is to alias the base class version in the 
derived class. But why the compiler would now require that you do that, I 
don't know. If that's the way that thnigs currently are, it starts to become a 
bit odd that the base class functions aren't automatically available. IIRC, 
the reason that they weren't before is so that you don't get cases where 
you're not aware of what all of the overloads in a class are and end up with a 
different function being called than you expected (so it's another one of the 
function-hijacking prevention features), and I that still applies, so I guess 
that that's why still have to do it. Still, it's weird.

TDPL may explain this. I don't know. I'd have to go digging. I'm 99.99% 
certain that it explains the alias bit at least.

- Jonathan M Davis


Re: how is this considered hiding methods?

2012-09-22 Thread Gor Gyolchanyan
On Saturday, 22 September 2012 at 07:48:02 UTC, Gor Gyolchanyan 
wrote:
Can someone please tell me why the following code gives these 
errors?


Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal 
animal_) hidden by BirdZoo is deprecated


Error: class main.ParrotZoo use of 
main.VertebrateZoo.take(Animal animal_) hidden by ParrotZoo is 
deprecated


/// The code:

class Animal { }
class Vertebrate { }
class Bird: Animal { }
class Parrot: Bird { }

class VertebrateZoo
{
void take(Animal animal_)
{
if(auto vertebrate = cast(Vertebrate)animal_)
take(vertebrate);
}

abstract void take(Vertebrate vertebrate_);
}

class BirdZoo: VertebrateZoo
{
override void take(Vertebrate vertebrate_)
{
if(auto bird = cast(Bird)vertebrate_)
take(bird);
}

abstract void take(Bird bird_);
}

class ParrotZoo: BirdZoo
{
override void take(Bird bird_)
{
if(auto parrot = cast(Parrot)bird_)
take(parrot);
}

abstract void take(Parrot parrot_);
}



I figured it out:

class BirdZoo: VertebrateZoo
{
alias VertebrateZoo.take take;

override void take(Vertebrate vertebrate_)
{
if(auto bird = cast(Bird)vertebrate_)
take(bird);
}

abstract void take(Bird bird_);
}

class ParrotZoo: BirdZoo
{
alias BirdZoo.take take;

override void take(Bird bird_)
{
if(auto parrot = cast(Parrot)bird_)
take(parrot);
}

abstract void take(Parrot parrot_);
}



how is this considered hiding methods?

2012-09-22 Thread Gor Gyolchanyan
Can someone please tell me why the following code gives these 
errors?


Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal 
animal_) hidden by BirdZoo is deprecated


Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal 
animal_) hidden by ParrotZoo is deprecated


/// The code:

class Animal { }
class Vertebrate { }
class Bird: Animal { }
class Parrot: Bird { }

class VertebrateZoo
{
void take(Animal animal_)
{
if(auto vertebrate = cast(Vertebrate)animal_)
take(vertebrate);
}

abstract void take(Vertebrate vertebrate_);
}

class BirdZoo: VertebrateZoo
{
override void take(Vertebrate vertebrate_)
{
if(auto bird = cast(Bird)vertebrate_)
take(bird);
}

abstract void take(Bird bird_);
}

class ParrotZoo: BirdZoo
{
override void take(Bird bird_)
{
if(auto parrot = cast(Parrot)bird_)
take(parrot);
}

abstract void take(Parrot parrot_);
}