Re: dup and arrays
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
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
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
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
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
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
-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
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
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.