Re: dup and arrays

2010-03-26 Thread Philippe Sigaud
On Sat, Mar 27, 2010 at 03:34, strtr  wrote:

> Ellery Newcomer Wrote:
>
> > I just noticed that dup does not dup deep.
> >
> > In a two second search I couldn't find any reason for or against, but
> > I'd kinda like it if
> >
> > auto r2 = r.dup;
> > r2[i][j] = 0;
> > r[i][j] = 1;
> > assert(r2[i][j] != r[i][j]);
> >
> > held.
>
> There have been discussions about this before.
> Here is the first I found (couldn't find my own .ddup request :)
>
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12631


I sent a proposal for deep dup a few hours after your discussion, bu no one
commented on it. And now I can't find it... hmm. Maybe the mail didn't make
it.

Anyway, here it is:

template TypeofDeepdup(T)
{
alias typeof(deepdup(T.init)) TypeofDeepdup;
}

ref Unqual!T deepdup(T)(T t) if (is(T == struct) && !is(T.Types))
{
staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}
return Unqual!T(tup);
}

Tuple!(staticMap!(TypeofDeepdup, T.Types))
deepdup(T)(T t) if (is(T.Types)) // Tuples
{
staticMap!(TypeofDeepdup, T.Types) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.field[i]);}
return tuple(tup);
}

Unqual!T deepdup(T)(T t) if (is(T == class))
{
staticMap!(TypeofDeepdup, typeof(t.tupleof)) tup;
foreach(i,Type; tup) { tup[i] = deepdup(t.tupleof[i]);}
return new Unqual!T(tup);
}

TypeofDeepdup!(ElementType!T)[] deepdup(T)(T t) if (isDynamicArray!T)
{
auto result = new TypeofDeepdup!(ElementType!T)[](t.length);
foreach(i, elem; t) result[i] = deepdup(elem);
return result;
}

TypeofDeepdup!(ElementType!T)[T.length] deepdup(T)(T t) if (isStaticArray!T)
{
TypeofDeepdup!(ElementType!T)[T.length] result = t;
foreach(ref elem; result) elem = deepdup(elem);
return result;
}

TypeofDeepdup!T* deepdup(T)(T* t)
{
return &deepdup(*t);
}

Unqual!T deepdup(T)(T t) if (!is(T == struct) && !is(T == class) &&
!isArray!T && !is(T.Types) && !isPointer!T)
{
return cast(Unqual!T)t;
}

It seems to work well enough for my purposes, but still has some
limitations: for example, it unqualifies everything (no more const /
immutable after dupping).

Philippe


Re: dup and arrays

2010-03-26 Thread strtr
Ellery Newcomer Wrote:

> I just noticed that dup does not dup deep.
> 
> In a two second search I couldn't find any reason for or against, but 
> I'd kinda like it if
> 
> auto r2 = r.dup;
> r2[i][j] = 0;
> r[i][j] = 1;
> assert(r2[i][j] != r[i][j]);
> 
> held.

There have been discussions about this before.
Here is the first I found (couldn't find my own .ddup request :)
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=12631


dup and arrays

2010-03-26 Thread Ellery Newcomer

I just noticed that dup does not dup deep.

In a two second search I couldn't find any reason for or against, but 
I'd kinda like it if


auto r2 = r.dup;
r2[i][j] = 0;
r[i][j] = 1;
assert(r2[i][j] != r[i][j]);

held.


Re: DMD2, Phobos: striding range

2010-03-26 Thread Philippe Sigaud
On Fri, Mar 26, 2010 at 11:16, Mihail Strashun  wrote:

> Hm, changing "ref" on lines 716 and 724 to "auto ref" changes nothing.
> Changing it to simply "auto" seems to solve problem.
>
> How "auto ref" feature is supposed to work? This (
> http://www.digitalmars.com/d/2.0/function.html ) description tends to
> match problem with stride, but as I have just said, it gives same error.
>

Then we both do not understand what auto ref functions can do. Or maybe it's
still a bit buggy?


Re: Never called destructor

2010-03-26 Thread Don

div0 wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

bearophile wrote:

div0:

scope x = new A("x");
y = new A("y");
x = y;

In my opinion it's better to not reassign references of scoped objects.
In real programs where possible it's better to write boring and stupid code :-)

Bye,
bearophile


Yeah, I was thinking about that and wondering whether in fact it should
be an error and disallowed.

I use scope because I want the instance on the stack for performance,
and allowing the scope ref to be reassigned buggers things up.

also consider:

import std.stdio;

class A {
string  _instance;

this(string instance) {
_instance = instance;
}

~this() {
writefln("A.~this @ 0x%x: %s", cast(void*)this, _instance);
}
}

A test() {
scope   x = new A("x");
autoy = new A("y");
x = y;
return y;
}

void main()
{
scope z = test();
writefln("main, z @ 0x%x, [%s]", cast(void*)z, z._instance);
}

output:

A.~this @ 0x962E40: y
main, z @ 0x962E40, [y]

This is clearly wrong, we are accessing a deleted object, and for some
reason we aren't getting a double delete of y, which we should.


Same as bug 3285 / bug 3516?


Re: Never called destructor

2010-03-26 Thread bearophile
div0:
> This is clearly wrong, we are accessing a deleted object, and for some
> reason we aren't getting a double delete of y, which we should.

Thank you for the nice example, I think it's doing the struct return 
optimization trick invented by Walter ages ago :-)

"scope" for objects is a very useful optimization, I can show you benchmarks, 
because DMD isn't able to perform escape analysis as recent HotSpot does. But I 
think Walter knows it's not safe (it can be made quite more safe if more sanity 
tests are added to DMD, but this decreases their flexibility and usefulness 
when you need more performance).

So don't use it to increase code safety, because it fails at that. Use it only 
where you can experimentally see a performance improvement. And where possible 
don't copy, reassign or return the reference of a scoped object :-) Objects in 
D are not meant to be copied. And the purpose of a scoped object is to exist 
only in a scope, to avoid a heap allocation. If you try to break free of this 
semantics you are on your own.

Do you want to write a bug report? I fear that the only way to make scoped 
objects fully semantically sound is to remove them from the language, and 
Walter was about to do it. But there are legit usages for scoped objects.

Bye,
bearophile


Re: Never called destructor

2010-03-26 Thread div0
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

bearophile wrote:
> div0:
>> scope x = new A("x");
>> y = new A("y");
>> x = y;
> 
> In my opinion it's better to not reassign references of scoped objects.
> In real programs where possible it's better to write boring and stupid code 
> :-)
> 
> Bye,
> bearophile

Yeah, I was thinking about that and wondering whether in fact it should
be an error and disallowed.

I use scope because I want the instance on the stack for performance,
and allowing the scope ref to be reassigned buggers things up.

also consider:

import std.stdio;

class A {
string  _instance;

this(string instance) {
_instance = instance;
}

~this() {
writefln("A.~this @ 0x%x: %s", cast(void*)this, _instance);
}
}

A test() {
scope   x = new A("x");
autoy = new A("y");
x = y;
return y;
}

void main()
{
scope z = test();
writefln("main, z @ 0x%x, [%s]", cast(void*)z, z._instance);
}

output:

A.~this @ 0x962E40: y
main, z @ 0x962E40, [y]

This is clearly wrong, we are accessing a deleted object, and for some
reason we aren't getting a double delete of y, which we should.

- --
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/

iD8DBQFLrQCTT9LetA9XoXwRApiDAJ90F6qYvnWiSs5SSuCLp9RHfV8yXQCeOYCF
A+zJeKRqVgnSC/JCQzxrghg=
=qpxe
-END PGP SIGNATURE-


Re: initializing immutable structs

2010-03-26 Thread bearophile
Paul D. Anderson:
> The primary difficulty is that I can't use a static initializer but need to 
> use a constructor instead. But the constructor isn't allowed as it's 
> non-constant expression. How do I declare the struct variable and initialize 
> it separately?
> 
> The second difficulty is that when I declare it immutable I get a "can't 
> implicitly convert an expression of type X to to immutable X" error. I tried 
> an explicit cast and that didn't work.

Do not use casts, forget they exist. In safe mode you can't use them.
Show us the code that doesn't work as you want, because I have no ESP powers.

This shows how you can use immutable structs:

struct Foo {
int x, y;
this(int xx, int yy) {
this.x = xx;
this.y = yy;
}
}

immutable struct Bar {
int x, y;
this(int xx, int yy) {
this.x = xx;
this.y = yy;
}
}

struct Spam {
int x, y;
immutable this(int xx, int yy) { // ?
this.x = xx;
this.y = yy;
}
}

void main() {
immutable Foo f1 = Foo(1, 2);
auto f2 = immutable(Foo)(1, 2);
Foo f3 = Foo(1, 2);
immutable Foo f4 = f3;
auto b1 = Bar(1, 2);
Bar b2 = Bar(1, 2);

Spam s1 = Spam(1, 2);
s1.x = 10;
}

But s1 is not immutable, I don't know what "immutable this()" means.

Bye,
bearophile


Re: DMD2, Phobos: striding range

2010-03-26 Thread Mihail Strashun

Philippe Sigaud wrote:



On Mon, Mar 8, 2010 at 13:00, Lars T. Kyllingstad 
 wrote:


It's definitely a bug.  I've reported it:

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


std.range use ref everywhere. I had to comment them out to get any 
composition to work. But the 'auto ref' feature added a release ago was 
made to solve this problem, I guess. Full-blown propagation of ref when 
you can have it, graceful stop when you cannot.


Hmm, I should try this as soon as I won't have a baby sleeping on me...



Hm, changing "ref" on lines 716 and 724 to "auto ref" changes nothing. 
Changing it to simply "auto" seems to solve problem.


How "auto ref" feature is supposed to work? This ( 
http://www.digitalmars.com/d/2.0/function.html ) description tends to 
match problem with stride, but as I have just said, it gives same error.