Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 18:41:19 -0400, bearophile   
wrote:


Thank you Steven for your explanations, I have done similar things in C  
and D, but I didn't understand what you meant.


A is always put first, that way, a pointer to a B can always be used as  
a pointer to an A.<


Are you sure C specs say doing this leads to defined behaviour?
(Recently from a discussion with Walter I have learnt that D follows  
exactly C specs regarding such defined/undefined things.)


Xt and the Berkeley sockets library relies on it.  If it's not in the  
spec, then it's a de-facto standard.  I think the defined behavior is that  
the first member of a struct is positioned at the same address as the  
struct itself.





What I would like is a common-sense approach to inheritance for structs
that just does not allow virtual methods or interfaces, and which does  
not

cast implicitly to the base (explicit cast is OK).  I think some designs
would benefit greatly from this simple feature.  I think it's more  
tricky

than I've described, but I think with some diligence it can be done.


I have desired some form of inheritance in D structs (before the  
creation of alias this, that so far I have not used much). I think  
Walter will not love this idea, but you can think more about its  
details, and then you can post it in the main D newsgroup.


Sadly, I think it is not much more than a wish.  I don't think Walter's  
mind can be changed on this.


-Steve


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Thank you Steven for your explanations, I have done similar things in C and D, 
but I didn't understand what you meant.

>A is always put first, that way, a pointer to a B can always be used as a 
>pointer to an A.<

Are you sure C specs say doing this leads to defined behaviour?
(Recently from a discussion with Walter I have learnt that D follows exactly C 
specs regarding such defined/undefined things.)


> What I would like is a common-sense approach to inheritance for structs  
> that just does not allow virtual methods or interfaces, and which does not  
> cast implicitly to the base (explicit cast is OK).  I think some designs  
> would benefit greatly from this simple feature.  I think it's more tricky  
> than I've described, but I think with some diligence it can be done.

I have desired some form of inheritance in D structs (before the creation of 
alias this, that so far I have not used much). I think Walter will not love 
this idea, but you can think more about its details, and then you can post it 
in the main D newsgroup.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Ali:
> For what it's worth, here is a code that uses 'dup' instead of 'copy'.

Oh, right. I have forgotten to say this to the OP. In D it's better to name it 
dup instead of copy.


>I know this is not the same thing; but I find this more intuitive:<

I agree, it's better for D.


>  A dup() const

Probably this is better, seeing your usage of it:

@property A dup() const

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 17:47:20 -0400, bearophile   
wrote:



Steven Schveighoffer:

I have hoped that at some point, structs can be auto-composed,
without a vtable, but you still have to do this manually.


I don't understand what you mean here :-)


I mean simple inheritance.  In C, there has always been manual  
inheritance.  You can see it with the sockaddr system, and even with the X  
toolkit widget system.


essentially, when you derive type B from type A in C++, you get this:

struct B
{
   A _a;
}

A is always put first, that way, a pointer to a B can always be used as a  
pointer to an A.


The other thing that happens is that function calls on B also use A as  
well.  This is not so easy in C, but in D it is currently quite trivial:


struct B
{
   A _a;
   alias _a this;
}

Then a call like b.methodOfA(); gets translated statically to  
b._a.methodOfA().


But there are things I don't like about this, such as you can *set* _a.   
To get around that, you define a property getter, but not a setter:


struct B
{
   private A _a;
   @property ref A a() {return _a;}
   alias a this;
}

What I would like is a common-sense approach to inheritance for structs  
that just does not allow virtual methods or interfaces, and which does not  
cast implicitly to the base (explicit cast is OK).  I think some designs  
would benefit greatly from this simple feature.  I think it's more tricky  
than I've described, but I think with some diligence it can be done.


-Steve


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Ali Çehreli

bearophile wrote:

Larry Luther:


Ok, I've added -w to compilation commands and I've switched back to pure text.<


Good :-)



What am I missing?<


I have modified a bit your D code like this, to have something with a main() 
that runs:


import std.c.stdio: puts;

class A {
int x, y;

void copy(const A a) {
puts("A copy");
x = a.x;
y = a.y;
}
}

class B : A {
int z;

void copy(const B b) {
puts("B copy");
super.copy(b);
z = b.z;
}
}

void main() {
A a1 = new A;
A a2 = new A;

B b1 = new B;
B b2 = new B;

a1.copy(a2); // should execute A.copy
a1.copy(b1); // should execute A.copy
b1.copy(b2); // should execute B.copy
b1.copy(a1); // should execute A.copy
}



I have also translated your the code to Java, because sometimes Java designers are more 
"correct" thant D designers:


class A {
int x, y;

void mycopy(A a) {
System.out.println("A mycopy");
x = a.x;
y = a.y;
}
}

class B extends A {
int z;

void mycopy(B b) {
System.out.println("B mycopy");
super.mycopy(b);
z = b.z;
}

public static void main(String[] args) {
A a1 = new A();
A a2 = new A();

B b1 = new B();
B b2 = new B();

a1.mycopy(a2); // should execute A.mycopy
a1.mycopy(b1); // should execute A.mycopy
b1.mycopy(b2); // should execute B.mycopy
b1.mycopy(a1); // should execute A.mycopy
}
}


The Java code compiles and runs with no errors, and prints:
A mycopy
A mycopy
B mycopy
A mycopy
A mycopy


But the D version is different. It seems you have found a small difference 
between Java and D that I didn't know about.

If I comment out the last line of the main() in the D code (b1.copy(a1);) and I 
compile the D code with -w it generates the warning I was talking about:

test.d(13): Error: class test.B test.A.copy(const const(A) a) is hidden by B


If I leave that line uncommented then the compilation stops with a different 
error:

test.d(33): Error: function test.B.copy (const const(B) b) is not callable 
using argument types (A)
test.d(33): Error: cannot implicitly convert expression (a1) of type test.A to 
const(B)

It seems in D the copy() of B replaces (hides) the copy() of A, even if no 
override is used. I don't know why D is designed this way, it can even be a 
design/implementation bug. But the presence of that warning suggests me this is 
expected, so it's probably just a difference between Java and D. If no one 
answers to this here then maybe later I will ask about this in the main D group.

Bye,
bearophile


For what it's worth, here is a code that uses 'dup' instead of 'copy'. I 
know this is not the same thing; but I find this more intuitive:


import std.stdio;
import std.string;

class A
{
int x, y;

this(int x, int y)
{
this.x = x;
this.y = y;
}

A dup() const
{
writeln("A copy");
return new A(x, y);
}

override string toString() const
{
return format("A(%s,%s)", x, y);
}
}

class B : A
{
int z;

this(int x, int y, int z)
{
super(x, y);
this.z = z;
}

override B dup() const
{
writeln("B copy");
return new B(x, y, z);
}

override string toString() const
{
return format("B(%s,%s,%s)", x, y, z);
}
}

void main() {
A a1 = new A(1, 1);
A a2 = new A(2, 2);
B b1 = new B(11, 11, 11);
B b2 = new B(22, 22, 22);

a1 = a2.dup;
assert((a1.x == 2) && (a1.y == 2));

a1 = b1.dup;
assert((a1.x == 11) && (a1.y == 11));
assert(typeid(a1) == typeid(B));  // <-- personality change

b1 = b2.dup;
assert((b1.x == 22) && (b1.y == 22) && (b1.z == 22));

// b1 = a1.dup; // <-- ERROR because not all As are Bs;
//   but as we know that a1 is
//   actually a B at this point;
//   we can down cast:
assert(cast(B)a1 !is null);
b1 = (cast(B)a1).dup;
assert((b1.x == 11) && (b1.y == 11) && (b1.z == 11));

writeln(a1);
writeln(a2);
writeln(b1);
writeln(b2);
}

Ali


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Steven Schveighoffer:
> I have hoped that at some point, structs can be auto-composed,
> without a vtable, but you still have to do this manually.

I don't understand what you mean here :-)

Bye,
bearophile


Re: Handy templates

2010-05-27 Thread Philippe Sigaud
>On Thu, May 27, 2010 at 01:00, Simen kjaeraas wrote:
>Here's a collection of templates I have created and use often.
>Some of these may be fit for inclusion in Phobos, others maybe not as much.
>Please critique, and post your own indispensable snippets.


Hey, cool idea ! Do you have a site to put them online?
The one you call Repeat, I call TypeNuple and use it almost on a daily
basis.

I have a bunch of those there:

http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html

I'm particularly fond of Compose, TemplateParametersTypeTuple, and
TemplateFunArity. Any comme

I also have templates acting specifically on typetuples there:

http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typetuple2.html

Strangely enough, I _have_ uses for things like StaticScan...



>


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Steven Schveighoffer
On Thu, 27 May 2010 17:04:35 -0400, Larry Luther   
wrote:



"bearophile"  wrote in message
news:ht4krg$17l...@digitalmars.com...
| On the base of your long experience do you like D so far?

There are many things that I like and I strongly agree with the failings
of C++ mentioned in the docs.  I don't like the asymmetry between structs
and classes.  I don't see why structs can't have inheritance.


Because of the slicing problem.  It's basically something like this:

struct A {virtual void foo();};

struct B : A {virtual void foo();};

void bar(A a)
{
  a.foo();
}

void baz()
{
  B b;
  bar(b); // b is "sliced" down to an A, and bar will now call A.foo  
instead of the expected B.foo.

}

The really bad part about this is, b might have set up its private  
variables so that to call A.foo would cause an error.


Same thing happens when returning by value.  The general issue is that  
inheritance and value types don't mix.  But reference types (that is,  
types that are always passed by reference) never have the slicing  
problem.  So classes in D (which are reference types) can inherit, while  
structs (which *can be* value types) cannot inherit.  I have hoped that at  
some point, structs can be auto-composed, without a vtable, but you still  
have to do this manually.  Luckily, it's not so much of a chore now that  
alias this is around.



 I haven't
had a memory leak problem in C++ for many years so the need for a GC  
seems

minor.
I can only assume that it's needed to support strings and dynamic arrays.
I'm pushing forward on the assumption that I'll discover the paradigm  
that

will make everything fall into place.


Yes, what it took for me is to write a project in C++ that could really  
have used a GC.


Essentially, here was my issue:

I had a protocol implemented with various messages with a function  
readMessage, which returned a newly-allocated message (which was a  
derivative of some base message type).  Then I used RTTI to cast the  
message to the right type to deal with the data.  However, what sucked is  
how I always had to free the message after receiving it.  I really just  
wanted to process the message and go to the next one.  A GC is great for  
this because memory management is not strewn throughout your code, you  
don't have to remember to free things you should free and leave things you  
should not.  On top of that, in my case, I had to figure out that I was  
responsible for freeing a message via documentation -- the language didn't  
really tell me.  In D, no matter where it comes from, you just forget  
about it, and whoever is responsible (GC or owner) cleans it up later.  It  
makes for much more readable and less error-prone code.


There are many other designs which work well with GC, and some which don't.

D has some power over the memory management so you can force your will  
upon it, but I've found that the best way to write D code is to embrace  
the GC.


Note also that memory leaks are not the worst problem with non-GC code.   
Freeing memory you weren't supposed to is worse.


  I'm anxiously waiting for something of the quality of the "Annotated  
C++

Reference Manual".


The D Programming Language is hitting bookstores soon, I think it will be  
a very good reference and educational book.


-Steve


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

> There are many things that I like and I strongly agree with the failings
> of C++ mentioned in the docs.

D is designed by people that have a good experience of C++, but while probably 
D avoids some C++ problems, it surely introduces a number of new issues :-)


> I don't like the asymmetry between structs
> and classes.  I don't see why structs can't have inheritance.

One of the first answers given here is that this D design avoids slicing bugs. 
See my other answer for more.


> I haven't
> had a memory leak problem in C++ for many years so the need for a GC seems 
> minor.
> I can only assume that it's needed to support strings and dynamic arrays.

A GC introduces other kind of leaks when there is a reference alive to an 
memory block that is supposed to be dead and not used any more. This can even 
be caused by the not precise nature of the current D GC, it can mismatch 
something for a pointer to a GC-managed memory zone, keeping it alive. For 
example in programs that use large associative arrays this seems a problem.

If you assume the presence of the GC this changes the way you write code. In 
theory you can be more relaxed. In practice D GC is not... well, you have to 
keep your eyes open anyway.


> I'm pushing forward on the assumption that I'll discover the paradigm that
> will make everything fall into place.

If you have some Java programming experience then you probably have nothing to 
discover regarding this aspect of D programming (here the main difference is 
that Oracle Java GC is more precise and quite more efficient).


> For example it took a great deal of time to 
> learn that "private" can be used several ways:

One of the good things of D design is that it tries to be uniform/consistent, 
in this case all other attributes can be used in the same ways :-)


>   I'm anxiously waiting for something of the quality of the "Annotated C++ 
> Reference Manual".

The problem here is that D is not very strictly defined in the first place, so 
it's harder to write a very strict D reference manual :-) But Andrei book is 
about to come out, that can be seen as a kind of official D2 reference.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
"bearophile"  wrote in message 
news:ht4krg$17l...@digitalmars.com...
| On the base of your long experience do you like D so far?

There are many things that I like and I strongly agree with the failings
of C++ mentioned in the docs.  I don't like the asymmetry between structs
and classes.  I don't see why structs can't have inheritance.  I haven't
had a memory leak problem in C++ for many years so the need for a GC seems 
minor.
I can only assume that it's needed to support strings and dynamic arrays.
I'm pushing forward on the assumption that I'll discover the paradigm that
will make everything fall into place.  It's hard to get the proper picture
from the documentation available on Digital-mars.  "Tango with D" didn't
significantly help either.  For example it took a great deal of time to 
learn
that "private" can be used several ways:

  private member_function () {)

  private {
member_function () {}
  }

  private:
member_function () {}

  I'm anxiously waiting for something of the quality of the "Annotated C++ 
Reference Manual".

Larry 




Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
See:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=110554


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

>Ok, I've added -w to compilation commands and I've switched back to pure text.<

Good :-)


>What am I missing?<

I have modified a bit your D code like this, to have something with a main() 
that runs:


import std.c.stdio: puts;

class A {
int x, y;

void copy(const A a) {
puts("A copy");
x = a.x;
y = a.y;
}
}

class B : A {
int z;

void copy(const B b) {
puts("B copy");
super.copy(b);
z = b.z;
}
}

void main() {
A a1 = new A;
A a2 = new A;

B b1 = new B;
B b2 = new B;

a1.copy(a2); // should execute A.copy
a1.copy(b1); // should execute A.copy
b1.copy(b2); // should execute B.copy
b1.copy(a1); // should execute A.copy
}



I have also translated your the code to Java, because sometimes Java designers 
are more "correct" thant D designers:


class A {
int x, y;

void mycopy(A a) {
System.out.println("A mycopy");
x = a.x;
y = a.y;
}
}

class B extends A {
int z;

void mycopy(B b) {
System.out.println("B mycopy");
super.mycopy(b);
z = b.z;
}

public static void main(String[] args) {
A a1 = new A();
A a2 = new A();

B b1 = new B();
B b2 = new B();

a1.mycopy(a2); // should execute A.mycopy
a1.mycopy(b1); // should execute A.mycopy
b1.mycopy(b2); // should execute B.mycopy
b1.mycopy(a1); // should execute A.mycopy
}
}


The Java code compiles and runs with no errors, and prints:
A mycopy
A mycopy
B mycopy
A mycopy
A mycopy


But the D version is different. It seems you have found a small difference 
between Java and D that I didn't know about.

If I comment out the last line of the main() in the D code (b1.copy(a1);) and I 
compile the D code with -w it generates the warning I was talking about:

test.d(13): Error: class test.B test.A.copy(const const(A) a) is hidden by B


If I leave that line uncommented then the compilation stops with a different 
error:

test.d(33): Error: function test.B.copy (const const(B) b) is not callable 
using argument types (A)
test.d(33): Error: cannot implicitly convert expression (a1) of type test.A to 
const(B)

It seems in D the copy() of B replaces (hides) the copy() of A, even if no 
override is used. I don't know why D is designed this way, it can even be a 
design/implementation bug. But the presence of that warning suggests me this is 
expected, so it's probably just a difference between Java and D. If no one 
answers to this here then maybe later I will ask about this in the main D group.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread bearophile
Larry Luther:

I'm nonplussed. Could you expand on why D class instances don't need to copy 
their contents and instances of D structs do?  While migrating C++ code to D 
I've had to convert "struct"s to "class"es because of the need for inheritance. 
 Why would the need to copy an instance's contents to another instance 
disappear?<

You are an experienced programmer, so if you think well about this topic you 
can probably understand the situation and the purposes behind D design as well 
or better than me. You probably know already what I can tell you about this 
topic.

D is different from C++, it's GC-based, and this changes many things and the 
way they have to be designed and used. D is designed to be a little "simpler" 
than C++, this means in some cases it prefers to do something in a safer way, 
instead in the most efficient way. D doesn't follow the zero overhead policy of 
C++, because it can lead to hairy code and because Java and C# have plenty 
shown it's often a waste of programmers time with no real performance gain.

In D structs don't support inheritance because they are designed to avoid the 
slicing bug, to be simpler, to be Plain Old Data. So D is designed to have 
different classes and structs because their usage style and purposes are 
different. When more complexity is needed, classes are there to be used. Even 
if currently DMD is not very good at optimizing away the class-derived 
overhead, better future D compilers can solve this. For some situations there's 
even the "scope" (that Walter is not so sure to keep, while other people like 
me have suggested the opposite, that is to extend its purpose to allocate an 
object inside the memory of another object) that can help performance. In Java 
the HotSpot is able to perform Escape Analysis on objects to avoid many heap 
allocations, and LDC is able to detect some simple cases and do the same.

By design D has no standard way to copy classes. I have not written very large 
object oriented D programs, but from what I have seen, I generally don't need 
to copy objects. I have often the need to move them around, put them in a 
collection, pull them out and put them in another collection, or create them in 
single instance, and so on. But I don't remember the last time I've had to copy 
a class instance in D. I just copy and add and remove class references. When I 
want I can keep many references to the same object and so on. In C++ programs 
this has to be done with care, because there is no GC, or you need some kind of 
smart pointer, while in D (in theory) you can relax and just let the GC do its 
thing.

My experience tells me that when you try to translate a program written in 
language X to language Y you always find some impedance (unless X and Y are 
almost the same language). But most times in language Y there are ways to solve 
the problem in a different way. You, as programmer, have to learn the way Y 
programs are usually written, its idioms and to avoid to force X idioms in Y 
and then complain that X idioms are not well represented in Y.

D design is far from perfect, and in future some things will probably need to 
be fixed (I have written enough text to fill two books about D features that 
can enjoy some change), but behind its design there is also lot of thought. So, 
you can show us some D code where you think there is a need to copy objects. If 
such uncommon need arises you can usually write your own copy functions.

Bye,
bearophile


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
"bearophile"  wrote in message 
news:ht4g3r$vu...@digitalmars.com...
| Larry Luther:
|
| > I did not get an error when building and running with DMD 2.042:
|
| I am using dmd v2.046, and I have taken the good habit of compiling 
with -w (warnings on).
| It seems this error I see is a blocking warning. It's a warning badly 
written, but do you agree it is saying something important? I presume your 
code can lead to bugs. I don't know why this is a warning instead of a true 
error...
|
| On your code it also complains for a missed "override" that is a good 
thing that eventually will become obligatory even without -w.
|
| When you post here I suggest you to avoid using HTML and use pure text.
|
| Bye,
| bearophile

Ok, I've added -w to compilation commands and I've switched back to pure 
text.

Given:

class A {
  int x, y;

  void copy (const A a) {
x = a.x;
y = a.y;
  }
}

class B : A {
  int z;

  void copy (const B b) {
super.copy( b);
z = b.z;
  }
}

A alpha = new A;
A bravo = new A;

B charlie = new B;
B delta = new B;

---

I don't see the problem with A.copy vs B.copy.
  alpha.copy( bravo)-- should execute A.copy
  alpha.copy( charlie)  -- should execute A.copy
  charlie.copy( delta)  -- should execute B.copy
  charlie.copy( alpha)  -- should execute A.copy

What am I missing?

Larry




Re: Finding and invoking struct destructors in D2

2010-05-27 Thread Don

div0 wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Pillsy wrote:

Hi, all,

I was wondering if there's any way to determine at compile time
whether a struct has a (non-trivial) destructor associated with it,
and whether there's any way to call that destructor without using
the delete operator. It seems like being able to do these two
things would allow you to make a container that plays well with
structs that are designed to do (say) reference counting, but I
don't see anything in the spec on the website that shows how this
might be accomplished.

Thanks!
Pillsy


Struct and class destructors are called __dtor.
This is undocumented though and therefore not guaranteed to work in
future versions or other(!) implementations:

struct foo {
~this()
{
}
}

int main(){

foo b;

static if(__traits(compiles, b.__dtor()))
{
pragma (msg, "got destructor");
}
else
{
pragma (msg, "no destructor");
}

return 0;
}


There are various struct destructor bugs still open though, so I
wouldn't count on being able to do a ref counted objects at the moment:

Most important is this one, which scuppers any change of doing a shared
ptr like struct:

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


Yup, that's #3 on my list of Ten Must-fix Bugs.

This related one is pretty bad too.
> http://d.puremagic.com/issues/show_bug.cgi?id=3323



- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFL/rG7T9LetA9XoXwRAkcyAJ9e/nXmNanAC9L4m6oCRbSk+EruzACfRgOJ
j0xFjV7F4Onz3rSFXeUkq+k=
=1nFQ
-END PGP SIGNATURE-


Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther

"bearophile"  wrote in message 
news:ht42el$6c...@digitalmars.com...
  ...
| There is no standard way to do this. In general you don't need to copy 
classes or their contents, because they are on the heap and managed by the 
GC.

I'm nonplussed.

Could you expand on why D class instances don't need to copy their contents 
and
instances of D structs do?  While migrating C++ code to D I've had to 
convert
"struct"s to "class"es because of the need for inheritance.  Why would the 
need
to copy an instance's contents to another instance disappear?

Larry 




Re: Newbie: copy, assignment of class instances

2010-05-27 Thread Larry Luther
Thank you, I had no idea that scope was doing this.
I thought that when the docs said that it was being allocated on the stack
that I was getting "struct" like behavior.

"Simen kjaeraas"  wrote in message 
news:op.vc0qlpjovxi...@biotronic-pc.home...
| Larry Luther  wrote:
|
| >
| >   scope B
| > alpha = new B;
| >
|
| 'scope B alpha;' allocates stack space for a reference to a B, and
| space for an instance of B. If the pointer changes, it is simply no longer
| referencing the instance on the stack.
|
| -- 
| Simen 




Re: Finding and invoking struct destructors in D2

2010-05-27 Thread Pillsy
== Quote from div0 (d...@users.sourceforge.net)'s article:
[...]
> Most important is this one, which scuppers any change of doing
> a shared ptr like struct:

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

Yeah, that basically kills the idea until the bug is fixed. :(

Once it is, I think a hasDestructor template would be a good thing
to have in the standard library.

Cheers,
Pillsy


Re: Finding and invoking struct destructors in D2

2010-05-27 Thread div0
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Pillsy wrote:
> Hi, all,
> 
> I was wondering if there's any way to determine at compile time
> whether a struct has a (non-trivial) destructor associated with it,
> and whether there's any way to call that destructor without using
> the delete operator. It seems like being able to do these two
> things would allow you to make a container that plays well with
> structs that are designed to do (say) reference counting, but I
> don't see anything in the spec on the website that shows how this
> might be accomplished.
> 
> Thanks!
> Pillsy

Struct and class destructors are called __dtor.
This is undocumented though and therefore not guaranteed to work in
future versions or other(!) implementations:

struct foo {
~this()
{
}
}

int main(){

foo b;

static if(__traits(compiles, b.__dtor()))
{
pragma (msg, "got destructor");
}
else
{
pragma (msg, "no destructor");
}

return 0;
}


There are various struct destructor bugs still open though, so I
wouldn't count on being able to do a ref counted objects at the moment:

Most important is this one, which scuppers any change of doing a shared
ptr like struct:

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

- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFL/rG7T9LetA9XoXwRAkcyAJ9e/nXmNanAC9L4m6oCRbSk+EruzACfRgOJ
j0xFjV7F4Onz3rSFXeUkq+k=
=1nFQ
-END PGP SIGNATURE-


Finding and invoking struct destructors in D2

2010-05-27 Thread Pillsy
Hi, all,

I was wondering if there's any way to determine at compile time
whether a struct has a (non-trivial) destructor associated with it,
and whether there's any way to call that destructor without using
the delete operator. It seems like being able to do these two
things would allow you to make a container that plays well with
structs that are designed to do (say) reference counting, but I
don't see anything in the spec on the website that shows how this
might be accomplished.

Thanks!
Pillsy


Re: problem with reduce on array of Tuples

2010-05-27 Thread Pelle

This has nothing to do with the tuples, I think.

test2.d:

import std.algorithm;

void main() {
map!((int x){return x+1;})([1,2,3,4,5]);
}

pp ~/dee% rdmd test2.d
test2.d(4): Error: delegate std.algorithm.__dgliteral1 cannot access 
frame of function __dgliteral1

test2.d(4): Error: template instance test2.main.map!(delegate int(int x)
{
return x + 1;
}
) error instantiating


It's a bug with the delegate literals inside the template.


problem with reduce on array of Tuples

2010-05-27 Thread Adrian Matoga
The following code fails to compile:

double sim(Document doc, string query)
{
alias Tuple!(double, "wij", double, "wiq") Weights;
Document q = Document.fromString(query);
Weights[] wi;
foreach (s; StrFilt(query))
wi ~= Weights(doc.termFreq(s) * invDocFreq(s), q.termFreq
(s) * invDocFreq(s));
return
reduce!((double acc, Weights w) { return acc + 0; /*w.wij
* w.wiq;*/ })(0.0, wi) /
(sqrt(reduce!((double acc, Weights w) { return acc + 0; /
*sqr(w.wij);*/ })(0.0, wi) *
 sqrt(reduce!((double acc, Weights w) { return acc + 0; /
*sqr(w.wiq);*/ }(0.0, wi);
}

and DMD 2.046 shows the following messages:
ir.d(119): Error: delegate std.algorithm.__dgliteral3 cannot access
frame of fun
ction __dgliteral3
ir.d(232): Error: template instance ir.Index.sim.Reduce!(delegate
double(double
acc, Tuple!(double,"wij",double,"wiq") w)
{
return acc + 0;
}
) error instantiating
ir.d(119):instantiated from here: reduce!(delegate double
(double acc, Tu
ple!(double,"wij",double,"wiq") w)
{
return acc + 0;
}
)


Is it my fault because of some misunderstanding or other error, or
should I report it as a bug in compiler/library?
The same function compiled well with reduce on StrFilt(query) instead
of Weights.

I attach the full source.
begin 644 ir.d
M:6UP;W)T('-T9"YS=&1I;SL-"FEM<&]R="!S=&0N65S(BP@(FYO(BP@(FYO="(L(")B=70B
M+"`B:70B+"`B:6XB+"`B:2(L(")Y;W4B+"`B:&4B+"`BR!R971UPT*"7-T$9R97$[#0H)#0H)=F]I9"!A9&1,:6YE*'-TPT*"0D)*RMF$9R97$H*0T*"7L-
M"@D);6%X1G)E<2`](&UI;E!O%MK97E=('X]
M(&1O8SL-"@D)?0T*"7T-"@D-"@ED;W5B;&4@:6YV1&]C1G)E<2AS=')I;F<@
M=&5R;2D-"@E[#0H)"6EF("AT97)M("%I;B!I;F1E>"D-"@D)"7)E='5R;B`P
M.PT*"0ER971UR!R971U2D-"@E[#0H)
M"61O=6)L95M$;V-U;65N=%T@PT*"0EW