Re: Why can't a method be virtual AND static at the same time?
Your motivation for this question is not clear. I can only guess. If you hope to get more performance by providing only one function, which is used as virtual and static at the same time, then this is impossible, because virtual functions are bound to a data instance by design. If you look for a possibility to type less code by skipping the instantiation of a class, then the use of an interface may be the wrong decision. If you want the virtual function to behave the same as the static function, then you can wrap the static function with the virtual one, like this: class ConsoleLogger : Logger { void print(string msg) { staticPrint(msg); } static void staticPrint(string msg) { writeln(msg); } } If you look for a possibility to override a static function like a virtual one, then you may be interested in so called system mixins (not part of D). System mixins are researched in aspect oriented programming (AOP). Read about it in this paper: Ichisugi, Y., Roudier, Y. (1998) Mixin Composition Strategies for the Modular Implementation of Aspect Weaving, Kyoto: Aspect Oriented Programming workshop at ICSE'98
Re: I don't like slices in D
On Thursday, 17 October 2013 at 22:30:52 UTC, Jonathan M Davis wrote: http://dlang.org/d-array-article.html It should be enlightening. Yes, now I understand this article, but only after I had this long discussion here. The relevant statement for me is The responsible party for managing a dynamic array's memory is the D runtime. For me this means that the programmer isn't suppose to manage allocation and reallocation of the array, because it is abstracted by the slices. Well, if it's so, then I have doubts that it will help to write performant code, BECAUSE of the abstraction. With this in mind I take back everything I said about slices and leave only a doubt that slices are performant. --- To clarify previous things: Whether the concatenation ~= appends without or with reallocation, depends on the available capacity of the left slice. The concatenation ~ never reallocates and creates always a new slice with capacity of 0. My prevoius example of the function removeElement(ref int[], int) will not work. The right implementation would be: void removeElement(ref int[] arr, int index) { arr[index..$-1] = arr[index+1..$].dup; arr.length--; arr.assumeSafeAppend(); }
I don't like slices in D
I expected slices to be in D (http://dlang.org/arrays.html) like they are in Go (http://blog.golang.org/go-slices-usage-and-internals). But they are not. Why the array have to be reallocated after the length of a slice is changed? It makes slices useless. Here a little example (it fails): void testSlices() { int[] dArr = [10, 11, 12]; int[] dSlice = dArr[0..2]; dSlice.length++; assert(dArr[2]==dSlice[2]); // failure }
Re: I don't like slices in D
On Thursday, 17 October 2013 at 18:21:30 UTC, David Eagen wrote: On Thursday, 17 October 2013 at 18:00:20 UTC, Vitali wrote: I expected slices to be in D (http://dlang.org/arrays.html) like they are in Go (http://blog.golang.org/go-slices-usage-and-internals). But they are not. Why the array have to be reallocated after the length of a slice is changed? It makes slices useless. Here a little example (it fails): void testSlices() { int[] dArr = [10, 11, 12]; int[] dSlice = dArr[0..2]; dSlice.length++; assert(dArr[2]==dSlice[2]); // failure } Change your slice to int[] dSlice = dArr[0..$] or [0..3]; The way you are doing it only takes the first 2 elements. Modified code: import std.stdio : writeln; void main() { int[] dArr = [10, 11, 12]; int[] dSlice = dArr[0..$]; assert(dArr[2] is dSlice[2]); // passes dSlice.length++; assert(dArr[2] == dSlice[2]); // passes } This doesn't answer my question. I repeat my question: Why does a reallocation accure AFTER a resize of the length of a slice, although there is still capacity?
Re: I don't like slices in D
On Thursday, 17 October 2013 at 18:29:47 UTC, John Colvin wrote: On Thursday, 17 October 2013 at 18:00:20 UTC, Vitali wrote: I expected slices to be in D (http://dlang.org/arrays.html) like they are in Go (http://blog.golang.org/go-slices-usage-and-internals). But they are not. Why the array have to be reallocated after the length of a slice is changed? It makes slices useless. Here a little example (it fails): void testSlices() { int[] dArr = [10, 11, 12]; int[] dSlice = dArr[0..2]; dSlice.length++; assert(dArr[2]==dSlice[2]); // failure } What's the use case for this? I haven't found myself ever needing something like that so far, but i'd be open to seeing an example. The use case is: void appendElement(ref int[] arr, int x) { arr ~= x; } void removeElement(ref int[] arr, int index) { arr = arr[0..index] ~ arr[index+1..$]; } void main() { int[] arr = [1, 2, 3]; arr.reserve(7); // Reserve capacity. arr.appendElement(4); // Here should be arr.removeElement(1); // no realocation of array, arr.appendElement(5); // but it is. assert(arr[1] == 3); assert(arr[2] == 4); assert(arr[3] == 5); } But maybe I don't understand what slices are for in D. Anyway in Go this works whithout reallocation.
Re: I don't like slices in D
I didn't expect that you would doubt that the array gets reallocated. Here a code to test: void appendElement(ref int[] arr, int x) { arr ~= x; } void removeElement(ref int[] arr, int index) { arr = arr[0..index] ~ arr[index+1..$]; } void main() { int* arrPtr1; int* arrPtr2; int[] arr = [1, 2, 3]; arr.reserve(7); // Reserve capacity. arr.appendElement(4); // I don't want a realocation arrPtr1 = arr.ptr; assert(arr.capacity==7); arr.removeElement(1); // happen here, assert(arr.capacity==3); arr.appendElement(5); // but it happens. arrPtr2 = arr.ptr; assert(arr[1] == 3); assert(arr[2] == 4); assert(arr[3] == 5); assert(arrPtr1 != arrPtr2); // different arrays - here } I'm not accusing D having a bug here. I'm saying that in my eyes a reallocation of the array referenced by the slice is not useful, when capacity is still available. @Ali Çehreli: You are right, Go's slices consist of three members. I have read it, although I din't test the code. In http://blog.golang.org/go-slices-usage-and-internals is said: Slicing does not copy the slice's data. It creates a new slice value that points to the original array. This makes slice operations as efficient as manipulating array indices. I repeat [...] as efficient as manipulating array indices. In D this is not the case and can't imagine what purpose can it suit else. @Meta and @David Eagen: My question is not about creating slices, but about make them shrink and grow without reallocating the referenced array.
Re: I don't like slices in D
On Thursday, 17 October 2013 at 19:05:32 UTC, Jonathan M Davis wrote: before incrementing dSlice's length, it'll print out 0. dSlice can't grow in place, because if it did, its new elements would overlap with those of dArr; dArr - [10, 11, 12] dSlice - [10, 11] Well this is only one part that makes no sense in my eyes. I thought the slices should be overlaping. Here, step by step: void main() { int* arrPtr1; int* arrPtr2; int[] arr = [1, 2, 3]; arrPtr1 = arr.ptr; arr.reserve(5); // reserve capacity arrPtr2 = arr.ptr; assert(arrPtr1 != arrPtr2); // ok, this makes sense assert(arr.capacity==7); // ok, this makes not so // much sense, but it's bigger than 5, // I guess it's ok // I reserved extra capacity. I got more // than I needed, but ok. arr ~= 4; // appending an element assert(arr[3]==4); arrPtr1 = arr.ptr; assert(arrPtr1==arrPtr2); // no reallocation, assert(arr.capacity==7); // good // I have enough capacity to append an // element; everything went fine arr.length++; assert(arr[4]==0 arr.length==5); arrPtr1 = arr.ptr; assert(arrPtr1==arrPtr2); // still no reallocation, assert(arr.capacity==7); // very good // Also the direct manipulation of // the length works, as long as a // value is assigned that is bigger // then the length. arr.length--; arrPtr1 = arr.ptr; assert(arrPtr1==arrPtr2); // good, but.. assert(arr.capacity==0); // - WHY ?? // after the length is reduced the // capacity is set to ZERO, this will // cause the array to be reallocated when // the length is increased by next time, // but what is the purpose of this? arr.length++; arrPtr1 = arr.ptr; assert(arrPtr1!=arrPtr2); // different arrays now! assert(arr.capacity==7); // yes, as expected }
Re: I don't like slices in D
On Thursday, 17 October 2013 at 20:01:37 UTC, David Nadlinger wrote: On Thursday, 17 October 2013 at 18:41:53 UTC, Vitali wrote: void removeElement(ref int[] arr, int index) { arr = arr[0..index] ~ arr[index+1..$]; } If you know that 'arr' is the only reference to this piece of data, you can use arr.assumeSafeAppend() to enable re-use of the remaining storage: http://dlang.org/phobos/object.html#.assumeSafeAppend David This is maybe what I have missed. I will take a closer look on it. Thank you. Thanks for every one who has posted here. I think the function mentioned by David Nadlinger will solve my problems. That's all for today ^^.
Is heap memory released after the termination of a thread?
Hello, in [1] is said that data defined in modules, if it's not shared, is copied for each thread. This means that new memory for this data is allocated every time when a new thread is started and when the thread terminates it is released [2]. But how about the memory created by this thread on the heap? Is it released, too, especialy when the garbage collector is turned off? Thank you. References [1] http://www.informit.com/articles/article.aspx?p=1609144seqNum=3 [2] http://dlang.org/module.html