Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 2015-02-23 21:30, Walter Bright wrote: Count me among those. In Java, write barriers make sense because Java uses the GC for everything. Pretty much every indirection is a GC reference. This is not at all true with D code. But since the compiler can't know that, it has to insert write barriers for all those dereferences regardless. The alternative would be to have two kind of pointers, one for GC allocated data and one for other kind of data. But I know you don't like that either. We kind of already have this, class references and regular pointers. But that would tie classes to the GC. I suspect it would be a terrible performance hit. It would be nice to have some numbers backing this up. -- /Jacob Carlborg
Re: A Refcounted Array Type
On 2/23/2015 9:59 PM, Jonathan M Davis via Digitalmars-d wrote: And delete is supposed to have been deprecated ages ago, but yeah, it _definitely_ shouldn't be considered @safe. Managing memory always is going to be unsafe. The idea is to encapsulate that, which RCArray shows how to do.
Re: A Refcounted Array Type
On Monday, February 23, 2015 15:28:21 Andrei Alexandrescu via Digitalmars-d wrote: > On 2/23/15 2:15 PM, Walter Bright wrote: > > This is pretty straightforward. > [snip] > > The code builds if you slap a "@safe:" at the top. There is one bug in > the compiler: "delete" must not be allowed in @safe code. The destructor > must be @trusted. And delete is supposed to have been deprecated ages ago, but yeah, it _definitely_ shouldn't be considered @safe. - Jonathan M Davis
Re: Stackless resumable functions
ahem. seems that you are right, and i outsmarted myself yet again. seems that my head is too small to keep three different task unmessed (forum discussion, plus two of my projects). sorry. If it's any consolation, I did accidentally use a C++ constructor in my first example.. I better sleep with one eye opened tonight ;)
Re: Stackless resumable functions
On Tue, 24 Feb 2015 03:22:10 +, bitwise wrote: > I think you're getting confused between "stackless" and "stackful" > resumable functions. ahem. seems that you are right, and i outsmarted myself yet again. seems that my head is too small to keep three different task unmessed (forum discussion, plus two of my projects). sorry. signature.asc Description: PGP signature
Re: Stackless resumable functions
On Tuesday, 24 February 2015 at 00:48:34 UTC, ketmar wrote: On Mon, 23 Feb 2015 23:10:28 +, bitwise wrote: you still thinking in terms of generators. Generator is a high-level construct, resumable routine is a low-level construct. latter is used to build the former. I think you're getting confused between "stackless" and "stackful" resumable functions. If I wanted stackful resumable functions, I would just use D's Fiber. If I wanted something lower level, I would simply make a D wrapper for boost::fcontext. http://www.boost.org/doc/libs/1_57_0/boost/context/fcontext.hpp #define RF "resumable function" // :) But, I am not talking about stackful RF. The control flow you're describing is that of a stackful RF. With stackless RFs, you can't just randomly switch control flow between coroutines, nor can you yield from nested stack frames. A stackless RF runs on the same stack as everything else. Only the local variables and RF's arguments are allocated on the heap. That said, I can't think of a lower level abstraction than what I have provided that would actually be useful... i don't even want to know what boost does. it stinks anyway. Maybe this is why you don't get what I'm saying ;) anywhere. any code. any delegate usage. it's a simple idiom of "switching control", where "function that calling delegate" can be seen as "delegate that calling the function". Again, I'm pretty sure you're thinking of stackful RFs. it's like building the brick house without having the bricks. Don't be silly, we're clearly building a bike shed here.
Re: Memory safety depends entirely on GC ?
On Tuesday, 24 February 2015 at 01:43:11 UTC, Andrei Alexandrescu wrote: This is a free world. Walter and I are working on a DIP. Please work on yours. I can't promise we'll choose to your liking, but this is the one way you can make your point heard and understood. What doesn't work is trash talk. I guarantee I recognize brilliance when I see it. So if you have a brilliant idea, it won't be missed. Have at it. One thing I cannot do is choose a solution that you prefer over one I prefer - this does remain a subjective topic. I can't help it. But please don't consider me an idiot because I don't like what you propose. I don't think you are being fair here. Even if not formally expressed as a DIP, at least Mark and myself have come up with fairly detailed explanations, in topic you participated in, so we can't really do as if it didn't existed. Also, I do not think this is a subjective matter. Yes there is a part of it that is matter of taste and is subjective, but overall there is a big chunk of objectively discussable things is there proposal, like language complexity and expressiveness added to the language. But here is mostly what I think is going on. We are discussion various issues, including make the GC faster, enable safe RC, make @nogc more usable (for instance exception usability), safe ref, enforcing type qualifier contraints, and so on... For each of these issues, solution are proposed. What I (and I think Mark would agree) propose would solve them all. Yes this is more complex than any of the solution proposed for each of these. But this is way simpler, and enable way more than having a unique, simpler solution for each of these problems.
Re: A Refcounted Array Type
On Tuesday, 24 February 2015 at 02:06:07 UTC, Walter Bright wrote: On 2/23/2015 5:41 PM, weaselcat wrote: On Monday, 23 February 2015 at 22:15:54 UTC, Walter Bright wrote: ref E opIndex(size_t i) return // here's the magic exactly what is this doing? I don't see this explained in DIP25 at all. The 'this' is passed by reference. So the 'return' is really 'return ref this', the rest is explained by DIP25. Oh, I see. That makes a lot more sense.
Re: A Refcounted Array Type
On 2/23/2015 5:41 PM, weaselcat wrote: On Monday, 23 February 2015 at 22:15:54 UTC, Walter Bright wrote: ref E opIndex(size_t i) return // here's the magic exactly what is this doing? I don't see this explained in DIP25 at all. The 'this' is passed by reference. So the 'return' is really 'return ref this', the rest is explained by DIP25.
Re: Memory safety depends entirely on GC ?
On 2/23/15 5:43 PM, Andrei Alexandrescu wrote: But please don't consider me an idiot because I don't like what you propose. Hmmm... actually I take that back :o). You are totally free to consider me such (or at least of intellect inferior to yours etc). What I mean is please don't consider me somehow socially or morally obligated to choose your solution just because you like it so much more than mine. Andrei
Re: Memory safety depends entirely on GC ?
On 2/23/15 5:23 PM, deadalnix wrote: So far, what I feel from you and Walter is the will to not go into that direction and instead created a myriad of hacks for various special cases. I do think this is wrong headed and generally not the way forward. Languages should provide the most generic and powerful tool so that interesting schemes can be implemented on top of it. This is a free world. Walter and I are working on a DIP. Please work on yours. I can't promise we'll choose to your liking, but this is the one way you can make your point heard and understood. What doesn't work is trash talk. I guarantee I recognize brilliance when I see it. So if you have a brilliant idea, it won't be missed. Have at it. One thing I cannot do is choose a solution that you prefer over one I prefer - this does remain a subjective topic. I can't help it. But please don't consider me an idiot because I don't like what you propose. Thanks, Andrei
Re: A Refcounted Array Type
On Monday, 23 February 2015 at 22:15:54 UTC, Walter Bright wrote: ref E opIndex(size_t i) return // here's the magic exactly what is this doing? I don't see this explained in DIP25 at all.
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 18:16:38 UTC, Andrei Alexandrescu wrote: That's not feasible. Code that assumes the class object will live forever can simply do things that are not allowed to code that must assume the object will go away at some determined point. Consider this which I just posted: class Widget { private char name[1024]; char[] getName() { return name[]; } ... } The typechecker must WHILE COMPILING WIDGET, NOT ITS CLIENT know whether getName() is okay or not. Let's use that exemple. Well I don't know of another way. I'm not sure if this is dishonest, but proposal has been made in this newgroup, by various person,s including myself. Let's get around the major concept. name is owned by the widget instance (let's call it w). That means its lifetime is the same as w's lifetime. w's owner will provide its lifetime. If w's owner is the GC, then its lifetime is infinite. if w's owner is some refounting system, its lifetime is defined by when the refcounting system will destroy it. getName here assumes the lifetime of the object is infinite. That's ok. It means you won't be able to call it when it is owned by a RC system. If you want to be able to do so, you'll ned have a way to specify the lifetime of the returned slice. For instance : class Widget { private char name[1024]; scope(char[]) getName() scope { return name[]; } ... } In this case, you can call the method when w is owned by a RC system, as it is now explicit to the caller that the lifetime of what is returned and the compiler can ensure the slice do not exceed its lifetime (ie w's lifetime). This require to be able to express lifetime and preferably ownership as well. So far, what I feel from you and Walter is the will to not go into that direction and instead created a myriad of hacks for various special cases. I do think this is wrong headed and generally not the way forward. Languages should provide the most generic and powerful tool so that interesting schemes can be implemented on top of it.
Re: A Refcounted Array Type
On 2/23/2015 4:13 PM, bearophile wrote: 5. bounds checking When you go past bounds of a built-in array you get an error located in the user code, while if you put a pre-condition in your Array struct to detect the same errors, you get a run-time error message located in that pre-condition instead. I'd like some way to solve this small problem of giving more correctly located error messages. In Contract programming lingo it's a problem of "blame management" (I'd also like a way to detect some compile-time out-of-bound errors for user-defined collections, but you said this is not worth the effort). This is off-topic. The point of the array class as presented is to show how a memory safe reference counted container can be built.
Re: A Refcounted Array Type
On 2/23/2015 5:01 PM, Max Klyga wrote: I thought that delete is deprecated, yet here Walter himself promotes a solution that uses it. Can we *PLEASE* finally deprecate things that are supposed to be deprecated and remove things that are supposed to be removed? That isn't the point. I could have well have used malloc/free, but I wanted the code example to be about how to make a memory safe ref counted container, not about the details of memory allocation. It demonstrates how 'return ref' is to be used.
Re: A Refcounted Array Type
I thought that delete is deprecated, yet here Walter himself promotes a solution that uses it. Can we *PLEASE* finally deprecate things that are supposed to be deprecated and remove things that are supposed to be removed? On 2015-02-23 22:15:46 +, Walter Bright said: This is pretty straightforward. More could be done: 1. small array optimization 2. support for ranges as constructor args 3. present a range interface 4. support for malloc/free instead of GC 5. bounds checking 6. the array[] and the count could be allocated together 7. array[] could be just a pointer but the basic idea is there, I didn't want to hide it behind all the other flesh a professional type would have. Note the return in opIndex(). This is DIP25 at work! Compile: dmd rcarray -unittest -main -dip25 === struct RCArray(E) { this(E[] a) { array = a.dup; start = 0; end = a.length; count = new int; *count = 1; } ~this() { if (count && --*count == 0) delete array; } this(this) { if (count) ++*count; } size_t length() { return end - start; } ref E opIndex(size_t i) return // here's the magic { return array[start + i]; } RCArray opSlice(size_t lwr, size_t upr) { RCArray result = this; result.start = start + lwr; result.end = start + upr; return result; } private: E[] array; size_t start, end; int* count; } unittest { static int[3] s = [7, 6, 4]; auto r = RCArray!int(s); assert(r.length == 3); assert(r[0] == 7); assert(r[1] == 6); assert(r[2] == 4); assert(*r.count == 1); { auto r2 = r; assert(r2[0] == 7); assert(r2[1] == 6); assert(r2[2] == 4); assert(*r.count == 2); r[1] = 3; assert(r2[0] == 7); assert(r2[1] == 3); assert(r2[2] == 4); } assert(*r.count == 1); auto r3 = r[1 .. 3]; r[2] = 9; assert(r3[0] == 3); assert(r3[1] == 9); /+ ref int test(ref RCArray!int rr) { return rr[1]; // this gives error } +/ }
Re: Let's Play Code Golf
On Monday, 23 February 2015 at 23:10:32 UTC, anonymous wrote: On Monday, 23 February 2015 at 20:21:20 UTC, Charles wrote: My solution (150 characters, 15 points): void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" %d",&n);real a=0,i=0;for(;i Link to problem site: https://www.hackerrank.com/challenges/leibniz Anyone care to do better? :) 126: void main(){import std.stdio;real n,a;for(readln;a=0,readf(" %f",&n);writefln("%.15f",a))while(--n>=0)a+=(n%2?-1:1)/(n+n+1);} Nice going. I didn't realize that the exponent operator was outside of std.math with ^^ which is why I used the ternary operator to achieve the same results, importing the standard library is probably the most expensive thing for this challenge. Yay learning things. With that in mind, and switching around --n to n--, we can get the code down to 120 characters: void main(){import std.stdio;real n,a=0;for(readln;readf(" %f",&n);writefln("%.15f",a))while(n--)a+=(-1)^^n/(n+n+1);} On Tuesday, 24 February 2015 at 00:03:55 UTC, bearophile wrote: Steve Sobel: It can get down to 155 using ranges, but those imports really are killer. You usually don't want to design a language for code golfing (but several exist, like http://esolangs.org/wiki/GolfScript ). Yeah I know that they're languages designed for this, but they feel like cheating for sure. Plus, GolfScript would be kinda odd on DLang's forums ;)
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 17:48:27 UTC, Andrei Alexandrescu wrote: I used to think the same. But then I considered typechecking things like: class Widget { private char name[1024]; char[] getName() { return name[]; } ... } Such code is safe if Widget is a GC class but not if it uses reference counting. This is not a valid argument against my point, simply expressing difficulties of implementation and lack of imagination of what this implementation can be. I'm not sure how to convey the idea anymore. That is an ownership issue and solutions exist for it. Several of them have been proposed already. It feels like we are gonna add a bazillion of stupid hacks to work around not introducing ownership into D. The return ref thing is one of them. What you are suggesting for refcounting is another.
Re: Last week for DConf 2015 submissions
On 24/02/2015 4:33 a.m., Adam D. Ruppe wrote: On Monday, 23 February 2015 at 05:41:51 UTC, Rikki Cattermole wrote: Perhaps we could get some UTU students involved with it? UVU. But will students will be attending too? I think they should be able to, it would be good exposure to them and give us some fresh people too. I agree, they should be given free passes. Especially if they contribute by e.g. being on a round table discussion.
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 15:35:52 UTC, Ola Fosheim Grøstad wrote: If you do excessive refcounting (ARC) and care about performance you actually need to let the implementor of C decide where the RC_counter is embedded... C providing facility to be refcountable do not equate with C's user want refcounting. It means that if C's user want it to be refcounted, it is gonna be faster.
Re: Stackless resumable functions
On Mon, 23 Feb 2015 23:10:28 +, bitwise wrote: >> you don't need to. if you really need to do that, you're doing >> something > > This makes no sense to me. A usage example may be helpful. you still thinking in terms of generators. generator is a high-level construct, resumable routine is a low-level construct. latter is used to build the former. >> resumable functions are not iterators. it's a slightly perversed flow >> control method. iteration/generation is one of the use cases. > > So how do you explain enumerators in C#, or generators in visual c++? as one of the possible high-level constructs that can be built with resumable routines. > http://www.boost.org/doc/libs/1_57_0/libs/coroutine/doc/html/index.html > > [quote] > Coroutine > Asymmetric coroutine Symmetric coroutine > [/quote] i don't even want to know what boost does. it stinks anyway. >> mimicking delegates allows to use resumable function in any code that >> expects delegate. > > If you can come up with even one example(with code) where it would make > sense to accept both coroutines and delegates, I will be very surprised. anywhere. any code. any delegate usage. it's a simple idiom of "switching control", where "function that calling delegate" can be seen as "delegate that calling the function". heh. anytime you need to switch the controlling side without rewriting the code. if you can't think out the use case for this, you still looking at resumable routines from the wrong POV. > In any case, I have revised my design. Generator(T) was redundant, so I > removed it. Below is something that I think is well formed enough for me > to start digging through the compiler for specifics. it's like building the brick house without having the bricks. you trying to build the house when you have to make bricks. sure, you can do that... and than cursing while smashing it into bricks when you need to build the fence. or building fences from houses. what you *really* trying to do is to build specific actor instead of building the foundation for programming with actors. building the foundation for actor model is way better and will allow you to build your generators easily. signature.asc Description: PGP signature
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 09:51:07 UTC, Manu wrote: This is going to sound really stupid... but do people actually use exceptions regularly? I'd say exception are exceptional in most code. That being said, unless the compiler can PROVE that no exception is gonna be thrown, you are stuck with having to generate a code path for unwinding that decrement the refcount. It means that you'll have code bloat (not that bad IMO, unless you are embeded) but more importantly, it means that most increment/decrement can't be optimized away in the regular path, as you must get the expected count in the unwinding path. Moreover, as you get some work to do on the unwind path, it becomes impossible to do various optimizations like tail calls. I think Walter is right when he says that switft dropped exception because of ARC. I've never used one. When I encounter code that does, I just find it really annoying to debug. I've never 'gotten' exceptions. I'm not sure why error codes are insufficient, other than the obvious fact that they hog the one sacred return value. Return error code have usually been an usability disaster for the simple reason that the do nothing behavior is to ignore the error. The second major problem is that you usually have no idea how where the error check is done, forcing the programmer to bubble up the error where it is meaningful to handle it. I'll agree though that this can't be changed at this point in the game. You say that's a terminal case? Generating code to properly implement a decrement chain during unwind impacts on the non-exceptional code path? Yes as you can't remove increment/decrement pairs as there are 2 decrement path (so there is pair). I agree. I would suggest if ARC were proven possible, we would like, switch. I'd like to see ARC support in D, but I do not think it makes sense as a default. 3. Memory safety is a requirement for any ARC proposal for D. Swift ignores memory safety concerns. What makes RC implicitly unsafe? Without ownership, one can leak reference to RCed object that the RC system do not see.
Re: D GC theory
On Mon, 23 Feb 2015 21:11:22 +, Sativa wrote: > How hard would it be to modify D's GC to do the following two things: > > 1. Scan the heap in the BG on another thread/cpu for compactification. needs read/write barriers added to generated code. a major slowdown for ALL memory access. > 2. Move blocks of memory in predictable(timewise) chunks that prevents > locking the main thread for any period of time. as you can't do "partial scans" without barriers... see above. > e.g., in the first step the GC finds some blocks of memory that need to > be freed/compacted. In the 2nd step it starts freeing/compacting it in > predictable pieces by limiting the time it takes while working. it's not freeing that takes time, it's scanning that takes time. after scanning is complete there is not much left to do. ah, well, if you have thousands of small objects, this can be slow too, but with such use case partial frees will lead to OOM situations very fast (as your code have to allocate as crazy to get to such situation). tl;dr: you can't do this in compiled language without introducing major slowdown for indirect memory access. and indirect memory access is used *everywhere*. you will not like the results. signature.asc Description: PGP signature
Re: D GC theory
On Monday, 23 February 2015 at 22:11:48 UTC, weaselcat wrote: On Monday, 23 February 2015 at 21:11:23 UTC, Sativa wrote: How hard would it be to modify D's GC to do the following two things: 1. Scan the heap in the BG on another thread/cpu for compactification. 2. Move blocks of memory in predictable(timewise) chunks that prevents locking the main thread for any period of time. e.g., in the first step the GC finds some blocks of memory that need to be freed/compacted. In the 2nd step it starts freeing/compacting it in predictable pieces by limiting the time it takes while working. The point is, that maybe the GC is ran more often but in smaller and predictable steps. That is, the GC should be able to calculate how long it will take to free/compact a block. If it takes too long then it simply does it in stages. This way, there is essentially a very predictable and consistent cpu usage with the GC running but never any major lag spikes that are going to throw real time behavior out the window. It would seem that such a "Feature" would be easy to implement by modifying the existing GC code to be "incremental". I'd prefer a constant 1-5% cpu usage given to the GC if it didn't blow up for no reason. This way, it being very predictable, just mean one has to get a slightly faster cpu to compensate or optimize the code slightly. Hi, D's GC actually is predictable. It will not collect unless you allocate. You can also disable it and manually collect. I use it this way and essentially use it as a smart freelist. That isn't the problem. The problem is that when it does collect, the time it takes is unpredictable. It could take 1us or 10m. If there is a cap on how long the GC can run at any particular time interval, then it it's time complexity is simple, predicable, and can be better used for RT applications. Effectively I would rather the GC run every second and spend a maximum of 1ms doing cleaning up(not necessarily finishing) instead of running when ever and potentially taking seconds to cleanup. It's all about how to actually distribute the GC running in time. As it stands now, it can run anytime and take as long as it wants. I'd rather have it running "continuously" but not take as long as it wants. By allowing it to run continuously, in short bursts, one should get the same long term behavior but not have the spikes in cpu usage which prevent its usefulness in RT applications.
Re: A Refcounted Array Type
Walter Bright: 5. bounds checking When you go past bounds of a built-in array you get an error located in the user code, while if you put a pre-condition in your Array struct to detect the same errors, you get a run-time error message located in that pre-condition instead. I'd like some way to solve this small problem of giving more correctly located error messages. In Contract programming lingo it's a problem of "blame management" (I'd also like a way to detect some compile-time out-of-bound errors for user-defined collections, but you said this is not worth the effort). Bye, bearophile
Re: Let's Play Code Golf
Steve Sobel: It can get down to 155 using ranges, but those imports really are killer. You usually don't want to design a language for code golfing (but several exist, like http://esolangs.org/wiki/GolfScript ). void main(){import std.algorithm,std.conv,std.range,std.stdio;foreach(n;stdin.byLine.drop(1))writefln("%.15f",iota(n.to!int).map!"(-1.0)^^a/(2*a+1)".sum);} You can remove one char: iota(n.to!int). n.to!int.iota. Bye, bearophile
Re: Let's Play Code Golf
On 02/23/15 21:21, Charles via Digitalmars-d wrote: > My solution (150 characters, 15 points): > > void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" > %d",&n);real a=0,i=0;for(;i
Re: A Refcounted Array Type
On 2/23/15 2:15 PM, Walter Bright wrote: This is pretty straightforward. [snip] The code builds if you slap a "@safe:" at the top. There is one bug in the compiler: "delete" must not be allowed in @safe code. The destructor must be @trusted. Understanding that this code (sans delete) is @safe (and the contribution of DIP25 to that) is of paramount importance. Making it possible to define @safe structs that are still able to return reference to their internals is crucial. It paves the way for truly safe reference counted classes. Andrei
Re: Let's Play Code Golf
On Monday, 23 February 2015 at 20:21:20 UTC, Charles wrote: My solution (150 characters, 15 points): void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" %d",&n);real a=0,i=0;for(;i Link to problem site: https://www.hackerrank.com/challenges/leibniz Anyone care to do better? :) 126: void main(){import std.stdio;real n,a;for(readln;a=0,readf(" %f",&n);writefln("%.15f",a))while(--n>=0)a+=(n%2?-1:1)/(n+n+1);}
Re: Stackless resumable functions
you don't need to. if you really need to do that, you're doing something This makes no sense to me. A usage example may be helpful. resumable functions are not iterators. it's a slightly perversed flow control method. iteration/generation is one of the use cases. So how do you explain enumerators in C#, or generators in visual c++? and, by the way, yielding is a two-way communication channel. http://www.boost.org/doc/libs/1_57_0/libs/coroutine/doc/html/index.html [quote] Coroutine Asymmetric coroutine Symmetric coroutine [/quote] you seem to stuck with iteration/generation idea, but this is not the way resumable functions should be seen. Not sure what to say to this.. mimicking delegates allows to use resumable function in any code that expects delegate. If you can come up with even one example(with code) where it would make sense to accept both coroutines and delegates, I will be very surprised. In any case, I have revised my design. Generator(T) was redundant, so I removed it. Below is something that I think is well formed enough for me to start digging through the compiler for specifics. interface MethodRange(T) { @property T front(); void popFront(); @property bool empty(); int opApply(int delegate(T) dg); } class __ResumeableMethod(T, METHOD_TYPE, CONTEXT_TYPE) : MethodRange!T { // method locals and passed args CONTEXT_TYPE* context; // -initially contains method entry point // -once executed, contains the resume address // -when finished, contains null void *fptr; // object reference for instance methods void *obj; T value; this(CONTEXT_TYPE* context, void *fptr, void *obj) { this.context = context; this.fptr = fptr; this.obj = obj; invoke(context, &value); } private T invoke(CONTEXT_TYPE *context, T *yielded_value) { fptr(context); fptr = context->return_address; if(fptr) *yielded_value = context->yielded_value; } @property override T front() { assert(!this.empty); return value; } override void popFront() { assert(!this.empty); invoke(context, &value); } @property override bool empty() { return fptr == null; } int opApply(int delegate(T) dg) { while(!this.empty) { if(dg(this.front)) return 1; } return 0; } } MethodRange!int myResumableMethod() { for(int i = 0; i < 10; ++i) yield i; } // the compiler would automatically transform the above // method into something like the one below MethodRange!int myResumableMethod() { void __method(__ContextFor__method *ctx) { for(ctx->i = 0; i < 10; ++i) { ctx->yielded_value = i; ctx->return_address = &return_pos; return; return_pos: } ctx->return_address = null; } return new __ResumeableMethod!int(new __ContextFor__method, &__method, null); } // usage void main() { foreach(num; myResumableMethod()) writeln(num); // or MethodRange!int[] methods; auto mr = myResumableMethod(); if(!mr.empty) methods ~= mr; for(int i = 0; i < methods.length; ) { auto mr = methods[i]; int status = mr.front; // handle item status.. mr.popFront(); if(mr.empty) methods.remove(i); else ++i; } }
Re: Let's Play Code Golf
On Monday, 23 February 2015 at 21:30:51 UTC, Steven Schveighoffer wrote: On 2/23/15 3:21 PM, Charles wrote: For the uninitiated, Code Golf is producing the correct answer to a question with minimal syntax (whitespace included). I found a couple questions on HackerRank, which allows D compilation. So far there's only two entries for D (mine and another) for the first problem. Here's the problem: In Calculus, the Leibniz formula for π is given by: 1 - 1/3 + 1/5 - 1/7 + 1/9 - ... = pi/4 You will be given an integer n. Your task is to print the summation of the Leibniz formula up to the nth term of the series correct to 15 decimal places. Input Format The first line contains the number of test cases (T) which is less than 100. Each additional line is a test case for a positive integer value (p) less than 10^7. Sample Input 2 10 20 Output Format Output T lines, with each line containing the summation up to nth term. Sample Output 0.760459904732351 0.772905951666960 Scoring This is a code golf question. The goal is to write a solution with as little code as possible. A correct submission with a source code of X characters will receive the following score: maxScore * (300 - X)/300 Any correct code longer than 300 characters will receive a score of maxScore * 0.001. MaxScore is the maximum score attainable for the problem. Note that whitespace is also treated as a character. My solution (150 characters, 15 points): void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" %d",&n);real a=0,i=0;for(;iLink to problem site: https://www.hackerrank.com/challenges/leibniz Anyone care to do better? :) I didn't beat your score, but I did it with ranges (full character count was 174): stdin.readln(); foreach(x; stdin.byLine) writefln("%0.15f", map!(a => (a&1?-1:1)/(2.0*a+1))(iota(x.to!int)).sum); I think if I didn't have to import so many things, I would have done much better :) -Steve It can get down to 155 using ranges, but those imports really are killer. void main(){import std.algorithm,std.conv,std.range,std.stdio;foreach(n;stdin.byLine.drop(1))writefln("%.15f",iota(n.to!int).map!"(-1.0)^^a/(2*a+1)".sum);}
Re: Let's Play Code Golf
I didn't beat your score, but I did it with ranges (full character count was 174): stdin.readln(); foreach(x; stdin.byLine) writefln("%0.15f", map!(a => (a&1?-1:1)/(2.0*a+1))(iota(x.to!int)).sum); I think if I didn't have to import so many things, I would have done much better :) -Steve Yeah, imports were my issue too. Especially with readln, because using that meant I needed std.conv. Why don't reals initialize to zero? That'd save me 4 characters! :P
Re: Dutch D Meetup
On Monday, 23 February 2015 at 21:07:04 UTC, George Sapkin wrote: Seems like there are some local meetups starting across the globe, but no Dutch one so far. Are there any D users from the Netherlands that would want to meetup and share their D stories? Cheers. I would surely come. Though have not really anything to share yet.
A Refcounted Array Type
This is pretty straightforward. More could be done: 1. small array optimization 2. support for ranges as constructor args 3. present a range interface 4. support for malloc/free instead of GC 5. bounds checking 6. the array[] and the count could be allocated together 7. array[] could be just a pointer but the basic idea is there, I didn't want to hide it behind all the other flesh a professional type would have. Note the return in opIndex(). This is DIP25 at work! Compile: dmd rcarray -unittest -main -dip25 === struct RCArray(E) { this(E[] a) { array = a.dup; start = 0; end = a.length; count = new int; *count = 1; } ~this() { if (count && --*count == 0) delete array; } this(this) { if (count) ++*count; } size_t length() { return end - start; } ref E opIndex(size_t i) return // here's the magic { return array[start + i]; } RCArray opSlice(size_t lwr, size_t upr) { RCArray result = this; result.start = start + lwr; result.end = start + upr; return result; } private: E[] array; size_t start, end; int* count; } unittest { static int[3] s = [7, 6, 4]; auto r = RCArray!int(s); assert(r.length == 3); assert(r[0] == 7); assert(r[1] == 6); assert(r[2] == 4); assert(*r.count == 1); { auto r2 = r; assert(r2[0] == 7); assert(r2[1] == 6); assert(r2[2] == 4); assert(*r.count == 2); r[1] = 3; assert(r2[0] == 7); assert(r2[1] == 3); assert(r2[2] == 4); } assert(*r.count == 1); auto r3 = r[1 .. 3]; r[2] = 9; assert(r3[0] == 3); assert(r3[1] == 9); /+ ref int test(ref RCArray!int rr) { return rr[1]; // this gives error } +/ }
Re: D GC theory
On Monday, 23 February 2015 at 21:11:23 UTC, Sativa wrote: How hard would it be to modify D's GC to do the following two things: 1. Scan the heap in the BG on another thread/cpu for compactification. 2. Move blocks of memory in predictable(timewise) chunks that prevents locking the main thread for any period of time. e.g., in the first step the GC finds some blocks of memory that need to be freed/compacted. In the 2nd step it starts freeing/compacting it in predictable pieces by limiting the time it takes while working. The point is, that maybe the GC is ran more often but in smaller and predictable steps. That is, the GC should be able to calculate how long it will take to free/compact a block. If it takes too long then it simply does it in stages. This way, there is essentially a very predictable and consistent cpu usage with the GC running but never any major lag spikes that are going to throw real time behavior out the window. It would seem that such a "Feature" would be easy to implement by modifying the existing GC code to be "incremental". I'd prefer a constant 1-5% cpu usage given to the GC if it didn't blow up for no reason. This way, it being very predictable, just mean one has to get a slightly faster cpu to compensate or optimize the code slightly. Hi, D's GC actually is predictable. It will not collect unless you allocate. You can also disable it and manually collect. I use it this way and essentially use it as a smart freelist.
Re: Let's Play Code Golf
On 2/23/15 5:04 PM, Andrei Alexandrescu wrote: On 2/23/15 1:30 PM, Steven Schveighoffer wrote: foreach(x; stdin.byLine) writefln("%0.15f", map!(a => (a&1?-1:1)/(2.0*a+1))(iota(x.to!int)).sum); Wonder why didn't you lead with the iota? -- Andrei Cuz that's how it came out my brain ;) -Steve
Re: Let's Play Code Golf
On 2/23/15 1:30 PM, Steven Schveighoffer wrote: foreach(x; stdin.byLine) writefln("%0.15f", map!(a => (a&1?-1:1)/(2.0*a+1))(iota(x.to!int)).sum); Wonder why didn't you lead with the iota? -- Andrei
Re: Let's Play Code Golf
On 2/23/15 3:21 PM, Charles wrote: For the uninitiated, Code Golf is producing the correct answer to a question with minimal syntax (whitespace included). I found a couple questions on HackerRank, which allows D compilation. So far there's only two entries for D (mine and another) for the first problem. Here's the problem: In Calculus, the Leibniz formula for π is given by: 1 - 1/3 + 1/5 - 1/7 + 1/9 - ... = pi/4 You will be given an integer n. Your task is to print the summation of the Leibniz formula up to the nth term of the series correct to 15 decimal places. Input Format The first line contains the number of test cases (T) which is less than 100. Each additional line is a test case for a positive integer value (p) less than 10^7. Sample Input 2 10 20 Output Format Output T lines, with each line containing the summation up to nth term. Sample Output 0.760459904732351 0.772905951666960 Scoring This is a code golf question. The goal is to write a solution with as little code as possible. A correct submission with a source code of X characters will receive the following score: maxScore * (300 - X)/300 Any correct code longer than 300 characters will receive a score of maxScore * 0.001. MaxScore is the maximum score attainable for the problem. Note that whitespace is also treated as a character. My solution (150 characters, 15 points): void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" %d",&n);real a=0,i=0;for(;ihttps://www.hackerrank.com/challenges/leibniz Anyone care to do better? :) I didn't beat your score, but I did it with ranges (full character count was 174): stdin.readln(); foreach(x; stdin.byLine) writefln("%0.15f", map!(a => (a&1?-1:1)/(2.0*a+1))(iota(x.to!int)).sum); I think if I didn't have to import so many things, I would have done much better :) -Steve
Re: D GC theory
Basically, I am simply wondering if the GC can "throttle" itself as to reduce the *maximum* time the program has to wait.
D GC theory
How hard would it be to modify D's GC to do the following two things: 1. Scan the heap in the BG on another thread/cpu for compactification. 2. Move blocks of memory in predictable(timewise) chunks that prevents locking the main thread for any period of time. e.g., in the first step the GC finds some blocks of memory that need to be freed/compacted. In the 2nd step it starts freeing/compacting it in predictable pieces by limiting the time it takes while working. The point is, that maybe the GC is ran more often but in smaller and predictable steps. That is, the GC should be able to calculate how long it will take to free/compact a block. If it takes too long then it simply does it in stages. This way, there is essentially a very predictable and consistent cpu usage with the GC running but never any major lag spikes that are going to throw real time behavior out the window. It would seem that such a "Feature" would be easy to implement by modifying the existing GC code to be "incremental". I'd prefer a constant 1-5% cpu usage given to the GC if it didn't blow up for no reason. This way, it being very predictable, just mean one has to get a slightly faster cpu to compensate or optimize the code slightly. It would be analogous to game programming. 1. We can have the GC steal, say, 1 fps to do it's work... 2. Or we can keep the GC asleep doing nothing until it gets so much work it has pause the entire engine for a 1/2 second dropping the fps down by half momentarily. This might happen every 1 minute or so but still unacceptable for most gamers. (assuming 30-60 fps) I'd prefer the first case.
Re: Let's Play Code Golf
On Mon, 23 Feb 2015 20:21:19 +, Charles wrote: > My solution (150 characters, 15 points): > > void main(){import std.stdio;int t,n;readf(" > %d",&t);while(t--){readf(" %d",&n);real > a=0,i=0;for(;i > Link to problem site: https://www.hackerrank.com/challenges/leibniz > > Anyone care to do better? :) Minor refactorings of your solution to get 15.7: https:// www.hackerrank.com/challenges/leibniz/submissions/code/11073459 Dirty solution (read and decrement a real as if it's a int), but passes the test cases.
Dutch D Meetup
Seems like there are some local meetups starting across the globe, but no Dutch one so far. Are there any D users from the Netherlands that would want to meetup and share their D stories? Cheers.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 2/22/2015 3:25 AM, Jacob Carlborg wrote: * Most good GC implementations need some kind of barrier (read or write, don't remember which). If I recall there are several people against this in the community Count me among those. In Java, write barriers make sense because Java uses the GC for everything. Pretty much every indirection is a GC reference. This is not at all true with D code. But since the compiler can't know that, it has to insert write barriers for all those dereferences regardless. I suspect it would be a terrible performance hit.
Let's Play Code Golf
For the uninitiated, Code Golf is producing the correct answer to a question with minimal syntax (whitespace included). I found a couple questions on HackerRank, which allows D compilation. So far there's only two entries for D (mine and another) for the first problem. Here's the problem: In Calculus, the Leibniz formula for π is given by: 1 - 1/3 + 1/5 - 1/7 + 1/9 - ... = pi/4 You will be given an integer n. Your task is to print the summation of the Leibniz formula up to the nth term of the series correct to 15 decimal places. Input Format The first line contains the number of test cases (T) which is less than 100. Each additional line is a test case for a positive integer value (p) less than 10^7. Sample Input 2 10 20 Output Format Output T lines, with each line containing the summation up to nth term. Sample Output 0.760459904732351 0.772905951666960 Scoring This is a code golf question. The goal is to write a solution with as little code as possible. A correct submission with a source code of X characters will receive the following score: maxScore * (300 - X)/300 Any correct code longer than 300 characters will receive a score of maxScore * 0.001. MaxScore is the maximum score attainable for the problem. Note that whitespace is also treated as a character. My solution (150 characters, 15 points): void main(){import std.stdio;int t,n;readf(" %d",&t);while(t--){readf(" %d",&n);real a=0,i=0;for(;i Link to problem site: https://www.hackerrank.com/challenges/leibniz Anyone care to do better? :)
Re: Mac Apps That Use Garbage Collection Must Move to ARC
Urgh. Product types masquerading as sum types. Give me a break will ya. -- Andrei 1. The product solution is more pleasant to work with, if you have no sugar for sum types like pattern matching. 2. It's the same as with exception specifications: Product types make ignoring the error path easier thus are more popular.
Re: Please tell me this is a bug?
On 2/21/15 9:27 PM, Peter Alexander wrote: On Sunday, 22 February 2015 at 01:24:09 UTC, Almighty Bob wrote: a += b; // Compiles with no ERROR! Please tell me that's a bug? Not a bug. From spec: http://dlang.org/expression.html#AssignExpression Assignment operator expressions, such as: a op= b are semantically equivalent to: a = cast(typeof(a))(a op b) Seems questionable to me. Anyone know the rationale? If a = b; is disallowed, I don't see why a += b; should be more acceptable. I think the docs are misleading. For example, this doesn't work: int a; int *b = &a; a += b; Error: incompatible types for ((a) += (b)): 'int' and 'int*' But this does: a = cast(typeof(a))(a + b); I think it only works if it's a numeric narrowing conversion, but I don't know for sure. I would be happy if this behavior changed as the OP expected. But I'm glad there isn't exactly an unfettered implicit cast in every op= operation. Does anyone know the true rules for this, and can they please file an PR on the docs? -Steve
Re: [NEEDING HELP] Translation of Ali Cehreli's book in French
Le 23/02/2015 07:13, Olivier Pisano a écrit : On Sunday, 22 February 2015 at 22:27:42 UTC, Raphaël Jakse wrote: Le 22/02/2015 14:00, Olivier Pisano a écrit : I did send you a first draft of the variable number of parameters chapter on Friday, on your gmail address. Did you get it ? Yes, I thought I answered to your mail. Sorry if I didn't. I read it quickly, it looks very well. Great, thank you very much for your work. I must find time to handle it, surely in the week. I also received proofreads for the first chapters, I will fix the translation soon. Thank you all for your work, that's great! Raphaël. Great, if you think something needs to be changed, do not hesitate. I started the translation of the next chapter this weekend and I should have something to show in the next few days. Looking forward for your work :-)
Re: Lightning talks?
On Mon, 2015-02-23 at 10:29 -0800, Andrei Alexandrescu via Digitalmars-d wrote: > DConf 2015 got a couple of lightning talk proposals. We obviously need a > few of those to consolidate them into a session. Any more takers? -- Andrei Let people sign up to do them at the conference. This management approach to lightening talks works well for PyConUK and ACCU. I am sure it works for others, but these are the two I know. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Memory safety depends entirely on GC ?
On 2/23/15 10:27 AM, Adam D. Ruppe wrote: On Monday, 23 February 2015 at 18:16:38 UTC, Andrei Alexandrescu wrote: The typechecker must WHILE COMPILING WIDGET, NOT ITS CLIENT know whether getName() is okay or not. Aye, I haven't been following this thread closely, but I thought of this case a while ago myself and it actually led me to the belief that the this pointer needs to be scope unless the class itself is designed solely for GC use; escaping anything through it must not be allowed for guaranteed memory safety if it is manually freed in any form, whether refcounting, RAII, or free. If this is scope, then the usage site has freedom of deallocation method. If not, it must be known at design time of the class itself. That's exactly right. There should be a DConf talk about that, apparently it's a widely misunderstood topic. -- Andrei
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 18:16:38 UTC, Andrei Alexandrescu wrote: The typechecker must WHILE COMPILING WIDGET, NOT ITS CLIENT know whether getName() is okay or not. Aye, I haven't been following this thread closely, but I thought of this case a while ago myself and it actually led me to the belief that the this pointer needs to be scope unless the class itself is designed solely for GC use; escaping anything through it must not be allowed for guaranteed memory safety if it is manually freed in any form, whether refcounting, RAII, or free. If this is scope, then the usage site has freedom of deallocation method. If not, it must be known at design time of the class itself.
Re: Memory safety depends entirely on GC ?
On 2/23/15 6:56 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= " wrote: On Sunday, 22 February 2015 at 17:01:45 UTC, Andrei Alexandrescu wrote: On 2/22/15 6:49 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= " wrote: No. There's also returning the reference from a member function, storing it in a passed-in reference (pointer, ref, out or slice), and passing it to other functions that in turn leak the reference, as well as throwing it. And leaking closures containing the reference. That's all that I can think of now... Consider class C { ... client code ... } alias T = RefCounted!C; ... more client code ... For reference counting to work transparently, access to the symbol "C" must be restricted. RefCounted obviously needs access to it. Client code should never have access to it, even in the definition of C. That means: 1. client code must not be able to declare variables of type C or issue calls like "new C" etc. No, this would require the class to be specialized for refcounting. But the memory management method needs to be the client code's decision; it can decide to manage some instance by refcounting, some by Unique!C, and leave others to the GC. The class implementer shouldn't need to care about all that. That's not feasible. Code that assumes the class object will live forever can simply do things that are not allowed to code that must assume the object will go away at some determined point. Consider this which I just posted: class Widget { private char name[1024]; char[] getName() { return name[]; } ... } The typechecker must WHILE COMPILING WIDGET, NOT ITS CLIENT know whether getName() is okay or not. 2. The type of "this" in methods of C must be RefCounted!C, not C. 3. Conversions of C to bases of C and interfaces must be forbidden; only their RefCounted!Base versions must be allowed. These two points have undesirable consequences: All consumers such objects need to be aware of the exact type, which includes the management strategy (RC, Unique, GC). But this is a violation of the principle of separation of concerns: a consumer shouldn't need to have information about the management strategy, it should work equally with `RefCounted!C`, `Unique!C` and bare (GC) `C`, as long as it doesn't take ownership of the resource. Well I don't know of another way. 4. Returning references to direct members of C must be restricted the same way they are for structs (see http://wiki.dlang.org/DIP25). A GC class object does not have that restriction. This is only a partial solution that doesn't work efficiently with anything other then value members. Slices, pointers and classes require introducing an additional, useless indirection, and that's not the only problem with it. So what do you propose instead? I am well aware of the disadvantages of a solution that _works_. Do you have something better? I think reference counting is an important component of a complete solution to resource management. D should implement world-class reference counting for safe code. For 1-4 above, although I am a staunch supporter of library-exclusive abstractions, I have reached the conclusion there is no way to implement RC in safe code for D classes without changes to the language. The more we realize that as a community the quicker we can move to effect it. I'm not sure this is what you're implying, but do you want to restrict it to classes only? Why not structs and slices, too? Structs and slices can be implemented @safe-ly after the advent of DIP25. It's classes that are the troublemaker. Of course I agree that a language change is necessary, but I'm convinced what you suggest above is not the right direction at all. (And I see that deadalnix has already replied and basically said the same thing.) That does awfully little to help. I'm telling things as they are. It's difficult to disagree with e.g. "a refcounted class cannot be implicitly convertible to Object and stay refcounted". In general, this and related proposals tend to limit themselves on memory management (as witnessed by the importance that `ref` and `@safe` play in them). This is too narrow IMO. A well thought-out solution can be equally applicable to the broader field of resource management. Looking forward to your insights. Andrei
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 2/23/15 3:27 AM, Walter Bright wrote: On 2/23/2015 1:50 AM, Manu via Digitalmars-d wrote: 1. Increment and decrement, ESPECIALLY DECREMENT, is EXPENSIVE in time and bloat because of exceptions. Swift does it by NOT HAVING EXCEPTIONS. This is not an option for D. This is going to sound really stupid... but do people actually use exceptions regularly? It doesn't matter if they do or not. It's a feature of D, and has to be supported. The only time it won't matter is if the intervening code is all 'nothrow'. You say that's a terminal case? Generating code to properly implement a decrement chain during unwind impacts on the non-exceptional code path? Since you don't believe me :-), write some shared_ptr code in C++ using your favorite compiler, compile it, and take a look at the generated assembler. I've asked you to do this before. It's necessary to understand how exception unwinding works in order to pontificate about ARC. BTW: http://asm.dlang.org Andrei
Re: Memory safety depends entirely on GC ?
On 2/22/15 8:50 PM, deadalnix wrote: On Sunday, 22 February 2015 at 20:48:58 UTC, Andrei Alexandrescu wrote: What ??? That mean writing all library code twice, for client that want GC and for these who don't. I'm not 100% convinced but it seems to me RC vs. GC is a class design time decision. The right strategy for memory management depend on the usage you'll do of an object, not of the object itself. I used to think the same. But then I considered typechecking things like: class Widget { private char name[1024]; char[] getName() { return name[]; } ... } Such code is safe if Widget is a GC class but not if it uses reference counting. Andrei
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 15:35:52 UTC, Ola Fosheim Grøstad wrote: On Monday, 23 February 2015 at 14:56:11 UTC, Marc Schütz wrote: violation of the principle of separation of concerns: a consumer shouldn't need to have information about the management strategy, it should work equally with `RefCounted!C`, `Unique!C` and bare (GC) `C`, as long as it doesn't take ownership of the resource. Just be aware that by not making the refcount part of C you either: 1. Need one more indirection. 2. Need a more complicated allocator to avoid alignment padding when C has 32byte/64 byte alignment requirements. 3. Risk having the refcount landing on a different cacheline, causing more cache misses. The refcount would be embedded right next to the object by the constructor of `RefCounted!C`, which is responsible for allocating memory for it, using an appropriate allocator. If you do excessive refcounting (ARC) and care about performance you actually need to let the implementor of C decide where the RC_counter is embedded... Of course there can be an additional (template) parameter to `RefCounted`, or it could be a different, user-implemented type altogether. But my point was that all of `Unique!C`, `RefCounted!C` and `C` should decay to `scope C`. This way, most consumers don't need to be aware of the actual wrapper type (if any) at all.
Re: Memory safety depends entirely on GC ?
On Monday, 23 February 2015 at 14:56:11 UTC, Marc Schütz wrote: violation of the principle of separation of concerns: a consumer shouldn't need to have information about the management strategy, it should work equally with `RefCounted!C`, `Unique!C` and bare (GC) `C`, as long as it doesn't take ownership of the resource. Just be aware that by not making the refcount part of C you either: 1. Need one more indirection. 2. Need a more complicated allocator to avoid alignment padding when C has 32byte/64 byte alignment requirements. 3. Risk having the refcount landing on a different cacheline, causing more cache misses. If you do excessive refcounting (ARC) and care about performance you actually need to let the implementor of C decide where the RC_counter is embedded...
Re: Last week for DConf 2015 submissions
On Monday, 23 February 2015 at 05:41:51 UTC, Rikki Cattermole wrote: Perhaps we could get some UTU students involved with it? UVU. But will students will be attending too? I think they should be able to, it would be good exposure to them and give us some fresh people too.
Re: Memory safety depends entirely on GC ?
On Sunday, 22 February 2015 at 17:01:45 UTC, Andrei Alexandrescu wrote: On 2/22/15 6:49 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= " wrote: No. There's also returning the reference from a member function, storing it in a passed-in reference (pointer, ref, out or slice), and passing it to other functions that in turn leak the reference, as well as throwing it. And leaking closures containing the reference. That's all that I can think of now... Consider class C { ... client code ... } alias T = RefCounted!C; ... more client code ... For reference counting to work transparently, access to the symbol "C" must be restricted. RefCounted obviously needs access to it. Client code should never have access to it, even in the definition of C. That means: 1. client code must not be able to declare variables of type C or issue calls like "new C" etc. No, this would require the class to be specialized for refcounting. But the memory management method needs to be the client code's decision; it can decide to manage some instance by refcounting, some by Unique!C, and leave others to the GC. The class implementer shouldn't need to care about all that. 2. The type of "this" in methods of C must be RefCounted!C, not C. 3. Conversions of C to bases of C and interfaces must be forbidden; only their RefCounted!Base versions must be allowed. These two points have undesirable consequences: All consumers such objects need to be aware of the exact type, which includes the management strategy (RC, Unique, GC). But this is a violation of the principle of separation of concerns: a consumer shouldn't need to have information about the management strategy, it should work equally with `RefCounted!C`, `Unique!C` and bare (GC) `C`, as long as it doesn't take ownership of the resource. 4. Returning references to direct members of C must be restricted the same way they are for structs (see http://wiki.dlang.org/DIP25). A GC class object does not have that restriction. This is only a partial solution that doesn't work efficiently with anything other then value members. Slices, pointers and classes require introducing an additional, useless indirection, and that's not the only problem with it. I think reference counting is an important component of a complete solution to resource management. D should implement world-class reference counting for safe code. For 1-4 above, although I am a staunch supporter of library-exclusive abstractions, I have reached the conclusion there is no way to implement RC in safe code for D classes without changes to the language. The more we realize that as a community the quicker we can move to effect it. I'm not sure this is what you're implying, but do you want to restrict it to classes only? Why not structs and slices, too? Of course I agree that a language change is necessary, but I'm convinced what you suggest above is not the right direction at all. (And I see that deadalnix has already replied and basically said the same thing.) In general, this and related proposals tend to limit themselves on memory management (as witnessed by the importance that `ref` and `@safe` play in them). This is too narrow IMO. A well thought-out solution can be equally applicable to the broader field of resource management.
Re: Last week for DConf 2015 submissions
On Monday, 23 February 2015 at 00:03:17 UTC, Andrei Alexandrescu wrote: At this point we don't have enough submissions to make DConf 2015 viable. Those we have are of good quality, but simply put more are needed. We're counting on our core community (i.e. frequent contributors to this forum) to both participate and spread the news about the conference. Expect two proposals from me by Friday too. I just simply didn't get around to writing them up in between all the science going on here yet. David
Re: [NEEDING HELP] Translation of Ali Cehreli's book in French
Bump ! I'd be interested in helping out with the translation. I call dibs on the 50th chapter (Member Functions), unless of course someone is already working on it.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 12:30:55 UTC, Russel Winder wrote: On Mon, 2015-02-23 at 19:50 +1000, Manu via Digitalmars-d wrote: O[…] This is going to sound really stupid... but do people actually use exceptions regularly? I've never used one. When I encounter code that does, I just find it really annoying to debug. I've never 'gotten' exceptions. I'm not sure why error codes are insufficient, other than the obvious fact that they hog the one sacred return value. D is just a whisker short of practical multiple-return-values. If we cracked that, we could use alternative (superior?) error state return mechanisms. I'd be really into that. […] Return codes for value returning functions only work if the function returns a pair, the return value and the error code: it is generally impossible to work with return values that serve the purpose of return value and error code. C got this fairly wrong, Go gets it fairly right. You wouldn't need new syntax (though I think multiple returns would be a nice addition), I think you can compile try/catch exception syntax into error codes internally.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 12:30:55 UTC, Russel Winder wrote: value and error code. C got this fairly wrong, Go gets it fairly right. It's the one feature about Go that makes Go code look really ugly... So I guess this is a very subjective issue. Posix is actually pretty consistent by returning "-1", even as a pointer, but if you don't write pure Posix code it becomes confusing.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Mon, 2015-02-23 at 19:50 +1000, Manu via Digitalmars-d wrote: > O[…] > This is going to sound really stupid... but do people actually use > exceptions regularly? > I've never used one. When I encounter code that does, I just find it > really annoying to debug. I've never 'gotten' exceptions. I'm not sure > why error codes are insufficient, other than the obvious fact that > they hog the one sacred return value. > D is just a whisker short of practical multiple-return-values. If we > cracked that, we could use alternative (superior?) error state return > mechanisms. I'd be really into that. […] Return codes for value returning functions only work if the function returns a pair, the return value and the error code: it is generally impossible to work with return values that serve the purpose of return value and error code. C got this fairly wrong, Go gets it fairly right. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 2/23/2015 1:50 AM, Manu via Digitalmars-d wrote: 1. Increment and decrement, ESPECIALLY DECREMENT, is EXPENSIVE in time and bloat because of exceptions. Swift does it by NOT HAVING EXCEPTIONS. This is not an option for D. This is going to sound really stupid... but do people actually use exceptions regularly? It doesn't matter if they do or not. It's a feature of D, and has to be supported. The only time it won't matter is if the intervening code is all 'nothrow'. You say that's a terminal case? Generating code to properly implement a decrement chain during unwind impacts on the non-exceptional code path? Since you don't believe me :-), write some shared_ptr code in C++ using your favorite compiler, compile it, and take a look at the generated assembler. I've asked you to do this before. It's necessary to understand how exception unwinding works in order to pontificate about ARC. 3. Memory safety is a requirement for any ARC proposal for D. Swift ignores memory safety concerns. What makes RC implicitly unsafe? You already know the answer - saving pointers to the RC object's payload that then outlive the RC'd object.
Re: Last week for DConf 2015 submissions
On 23 February 2015 at 01:30, Adam D. Ruppe via Digitalmars-d wrote: > I could prolly do two talks... especially if someone else wants to suggest a > topic. Heck, I could improvise in a round table or something too. I'd happily be on a panel talk. :)
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 23 February 2015 at 20:24, Jakob Ovrum via Digitalmars-d wrote: > On Monday, 23 February 2015 at 01:38:35 UTC, Manu wrote: >> >> On 23 February 2015 at 07:47, Walter Bright via Digitalmars-d >> >> wrote: >>> >>> On 2/22/2015 8:36 AM, Manu via Digitalmars-d wrote: I have no idea where to start. >>> >>> >>> >>> Start by making a ref counted type and see what the pain points are. >> >> >> All my ref counting types fiddle with the ref in every assignment, or >> every function call and return. Unless the language has some sort of >> support for ref counting, I don't know how we can do anything about >> that. > > > There's no move constructor in D, so how did you manage that? I wrote it above. struct Thing { T *instance; this(this) { Inc(instance); } ~this() { Dec(instance); } // this would really assist RC when 'scope' is inferred liberally. this(this) scope {} ~this() scope {} } In this case, rc is part of the instance; no reason to separate it when RC is not a generalised concept. Of course the structure can be generalised and fiddled/meta-ed to suit purpose in any number of ways. Inc's and Dec's galore! I'm not sure what a move constructor would give me over this.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 01:38:35 UTC, Manu wrote: On 23 February 2015 at 07:47, Walter Bright via Digitalmars-d wrote: On 2/22/2015 8:36 AM, Manu via Digitalmars-d wrote: I have no idea where to start. Start by making a ref counted type and see what the pain points are. All my ref counting types fiddle with the ref in every assignment, or every function call and return. Unless the language has some sort of support for ref counting, I don't know how we can do anything about that. There's no move constructor in D, so how did you manage that?
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 23 February 2015 at 16:50, Walter Bright via Digitalmars-d wrote: > On 2/22/2015 9:53 PM, Manu via Digitalmars-d wrote: >> >> It's got nothing to do with doing work. ARC (or something like it) is >> almost religiously opposed. We can't even have a reasonable >> conversation about it, or really explore it's implications before >> someone (that ideally know's what they're doing) thinks about writing >> code. > > > I participated in a very technical thread here on implementing ARC in D. I > wanted to make it work - nothing was off the table, language changes, > special features, etc. > > http://www.digitalmars.com/d/archives/digitalmars/D/draft_proposal_for_ref_counting_in_D_211885.html > > It was just unworkable, and nobody who participated in that thread had > workable ideas on moving forward with it. Nothing since has come up that > changes that. If you've got some ideas, please present them taking into > account the issues brought up in that thread. Wow, I missed that one it seems. I'll catch up. > Also, please take into account; proposals will not get much of a reception > if they ignore these points: > > 1. Increment and decrement, ESPECIALLY DECREMENT, is EXPENSIVE in time and > bloat because of exceptions. Swift does it by NOT HAVING EXCEPTIONS. This is > not an option for D. This is going to sound really stupid... but do people actually use exceptions regularly? I've never used one. When I encounter code that does, I just find it really annoying to debug. I've never 'gotten' exceptions. I'm not sure why error codes are insufficient, other than the obvious fact that they hog the one sacred return value. D is just a whisker short of practical multiple-return-values. If we cracked that, we could use alternative (superior?) error state return mechanisms. I'd be really into that. I'll agree though that this can't be changed at this point in the game. You say that's a terminal case? Generating code to properly implement a decrement chain during unwind impacts on the non-exceptional code path? > 2. As far as I can tell, the idea of flipping a compiler switch and the GC > switches to ref counting is a pipe dream fantasy. You can probably make such > a scheme work with a very limited language like Javascript, but it is never > going to work with D's support for low level programming. The way RC and GC > work is different enough that different user coding techniques will be used > for them. I agree. I would suggest if ARC were proven possible, we would like, switch. > 3. Memory safety is a requirement for any ARC proposal for D. Swift ignores > memory safety concerns. What makes RC implicitly unsafe?
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 07:19:56 UTC, Paulo Pinto wrote: Personally I think what matters is getting D's situation regarding memory management sorted out, regardless out it will look like in the end. This is exactly right, either 1. The compiler takes care of allocation/deallocations and makes refcounting part of the language implementation (but not necessarily the semantics). or 2. If allocation/deallocation is not the compiler's responsibility then RC should be a library solution based on efficient generally useful counter-semantics build blocks. A compiler solution for RC and manual allocations is a firefighter solution where all similar use cases suffers. I.e. when you want something similar to, but not exactly like what the compiler provides... If I am a bit too quick jumping the gun about GC, is that I have embraced GC languages in my line of work, so I tend to be aware that not all GCs are made alike and some like the ones from e.g. Aonix are good enough for real time situations, the ones someone dies if the GC runs on the wrong moment. Maybe such GC quality is impossible to achieve in D, I don't know. Well, hard real time does not mean fast, it means "bounded execution time". GC will is not suitable for a lot of reasons when you want to get the most out of the hardware (just memory requirements on diskless systems is sufficient to disqualify GC). When people use the term "real time" on the forums, they usually just mean hardware-efficient and low latency.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 09:01:23 UTC, Daniel Murphy wrote: "Ola Fosheim Grøstad" " wrote in message news:hwwotfmkjvwsempqi...@forum.dlang.org... I mean that the optimizer does not know what _rc is. The optimizer can only elide what it can prove, by sound logic, not by assumptions. The whole point of compiler-supported RC is that the optimizer can make assumptions. Yes, but then it makes no sense to tell Manu that he should use a library RC... It is nice to see at least one person admit that D needs to depart from modular arithmetic to solve real world problems... Because that is the implication of your statement. ;)
Re: Mac Apps That Use Garbage Collection Must Move to ARC
"Ola Fosheim Grøstad" " wrote in message news:hwwotfmkjvwsempqi...@forum.dlang.org... I mean that the optimizer does not know what _rc is. The optimizer can only elide what it can prove, by sound logic, not by assumptions. The whole point of compiler-supported RC is that the optimizer can make assumptions.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 08:50:28 UTC, Walter Bright wrote: On 2/23/2015 12:33 AM, Tobias Pankrath wrote: On Monday, 23 February 2015 at 08:27:52 UTC, Ola Fosheim Grøstad wrote: Thanks to the messed up modular arithmetics that D has chosen you cannot assume the a non-shared live object does not have a rc==0 due to wrapping integers, in the general case. You mean when there are more than 2^64 references to the object? Yeah, it'll wrap when there are more references than can even theoretically fit in the address space. I'm not worried about it :-) You don't worry about a lot of things that you ought to worry about :-P
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 08:33:59 UTC, Tobias Pankrath wrote: You mean when there are more than 2^64 references to the object? I mean that the optimizer does not know what _rc is. The optimizer can only elide what it can prove, by sound logic, not by assumptions.
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 06:51:21 UTC, Walter Bright wrote: 4. DIP25, now implemented, is a way to address memory safety in D while using reference counting. Any proposal for ARC needs to, at least, understand that proposal. I asked further up in the thread if coroutines can hold onto "return ref", e.g. does the compiler prevent a yield? It would be nice if you and Andrei admitted that you are in the land of complicated linear typing with "return ref".
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On 2/23/2015 12:33 AM, Tobias Pankrath wrote: On Monday, 23 February 2015 at 08:27:52 UTC, Ola Fosheim Grøstad wrote: Thanks to the messed up modular arithmetics that D has chosen you cannot assume the a non-shared live object does not have a rc==0 due to wrapping integers, in the general case. You mean when there are more than 2^64 references to the object? Yeah, it'll wrap when there are more references than can even theoretically fit in the address space. I'm not worried about it :-)
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 08:27:52 UTC, Ola Fosheim Grøstad wrote: On Monday, 23 February 2015 at 01:41:17 UTC, Adam D. Ruppe wrote: On Monday, 23 February 2015 at 01:38:35 UTC, Manu wrote: All my ref counting types fiddle with the ref in every assignment, or every function call and return. Hmm, the optimizer could potentially tell "inc X; dec X;" is useless and remove it without knowing what it is for. INPUT: try{ nonsharedobj._rc++; … } finally { nonsharedobj._rc--; if(nonsharedobj._rc==0) destroy… } OPTIMIZED: try{ … } finally { if(nonsharedobj._rc==0) destroy… } Thanks to the messed up modular arithmetics that D has chosen you cannot assume the a non-shared live object does not have a rc==0 due to wrapping integers, in the general case. You mean when there are more than 2^64 references to the object?
Re: Mac Apps That Use Garbage Collection Must Move to ARC
On Monday, 23 February 2015 at 01:41:17 UTC, Adam D. Ruppe wrote: On Monday, 23 February 2015 at 01:38:35 UTC, Manu wrote: All my ref counting types fiddle with the ref in every assignment, or every function call and return. Hmm, the optimizer could potentially tell "inc X; dec X;" is useless and remove it without knowing what it is for. INPUT: try{ nonsharedobj._rc++; … } finally { nonsharedobj._rc--; if(nonsharedobj._rc==0) destroy… } OPTIMIZED: try{ … } finally { if(nonsharedobj._rc==0) destroy… } Thanks to the messed up modular arithmetics that D has chosen you cannot assume the a non-shared live object does not have a rc==0 due to wrapping integers, in the general case.