Struct that destroys its original handle on copy-by-value
Hello all, A design question that came up during the hackathon held during the last Berlin D Meetup. I was trying to come up with a range that can be copied by value, but when this is done, destroys the original handle. The idea would be behaviour something like this: auto originalRange = myWeirdRange(whatever); originalRange.take(10).writeln; assert(originalRange.empty, "The original handle points to an empty range after copy-by-value."); A very minimal prototype (missing out the details of front and popFront as irrelevant) would be something like: struct MyWeirdRange (R) if (isInputRange!R) { private: R* input_; // Assumed to never be empty, FWIW. I'm missing out // a template check on that for brevity's sake. public: this (return ref R input) { /* return ref should guarantee the pointer * is safe for the lifetime of the struct, * right ... ? */ this.input_ = &input; } bool empty () @property { return this.input_ is null; } auto front () @property { ... } void popFront () { ... } void opAssign (ref typeof(this) that) { /* copy the internal pointer, then * set that of the original to null */ this.input_ = that.input_; that.input_ = null; } } Basically, this is a range that would actively enforce the principle that its use is a one-shot. You copy it by value (whether by direct assignment or by passing it to another function), you leave the original handle an empty range. However, the above doesn't work; even in the event of a direct assignment, i.e. newRange = originalRange; ... the opAssign is never called. I presume this is because of the ref-parameter input, but it's not obvious to me according to the description here why this should be: http://dlang.org/operatoroverloading.html#assignment Can anyone clarify what's going on here? Anyway, my main question is: is this design idea even feasible in principle, or just a bad idea from the get-go? And if feasible -- how would I go about it? Thanks & best wishes, -- Joe
Why hide a trusted function as safe?
Is there a reason why you would hide the fact that a function is trusted rather than safe? Technically it doesn't matter, right? To me, it seems like this would give wrong assumptions to the caller. The reason I ask is because I found the following in std.concurrency: @property Tid thisTid() @safe { // TODO: remove when concurrency is safe auto trus = delegate() @trusted { if( thisInfo.ident != Tid.init ) return thisInfo.ident; thisInfo.ident = Tid( new MessageBox ); return thisInfo.ident; }; return trus(); }
Re: Struct that destroys its original handle on copy-by-value
On Sunday, 26 July 2015 at 11:30:16 UTC, Joseph Rushton Wakeling wrote: Hello all, A design question that came up during the hackathon held during the last Berlin D Meetup. [...] Sounds like unique_ptr (so UniqueRange might be a nice name). Maybe you can get some ideas from that.
Re: Why hide a trusted function as safe?
On Sunday, 26 July 2015 at 11:38:31 UTC, simendsjo wrote: Is there a reason why you would hide the fact that a function is trusted rather than safe? Technically it doesn't matter, right? To me, it seems like this would give wrong assumptions to the caller. The reason I ask is because I found the following in std.concurrency: @property Tid thisTid() @safe { // TODO: remove when concurrency is safe auto trus = delegate() @trusted { if( thisInfo.ident != Tid.init ) return thisInfo.ident; thisInfo.ident = Tid( new MessageBox ); return thisInfo.ident; }; return trus(); } As far as I know, it doesn't matter. Both @safe and @trusted functions must be memory safe. So I don't see a point in doing that delegate dance. But it doesn't make a difference to the caller either. They can't assume any more or less about an @safe function than about an @trusted one.
Re: Struct that destroys its original handle on copy-by-value
On 26/07/15 13:45, Martijn Pot via Digitalmars-d-learn wrote: Sounds like unique_ptr (so UniqueRange might be a nice name). Maybe you can get some ideas from that. There is already a Unique in std.typecons. However, I'm not sure that it's doing what I require. Example: Unique!Random rng = new Random(unpredictableSeed); rng.take(10).writeln; ... will fail with an error: Error: struct std.typecons.Unique!(MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 7LU, 2636928640u, 15LU, 4022730752u, 18LU)).Unique is not copyable because it is annotated with @disable My aim by contrast is to _allow_ that kind of use, but render the original handle empty when it's done.
Re: Why hide a trusted function as safe?
On Sunday, 26 July 2015 at 11:38:31 UTC, simendsjo wrote: Is there a reason why you would hide the fact that a function is trusted rather than safe? Technically it doesn't matter, right? To me, it seems like this would give wrong assumptions to the caller. The Phobos idiom you've seen there is to have little trusted blocks inside an otherwise safe function. (That specific example seems unnecessary since there's no other code around it, but often the @trusted part is just a small bit of the whole function.) The idea is to get the @safe checks for everywhere you can, then use the @trusted delegate to escape from that for just a couple lines so you manually check that part while having more confidence in the rest of the function. If the whole function is marked @trusted, the compiler doesn't try to check it at all - it just takes your word for it. There was a bit of argument about this a while ago in bugzilla, not everyone agrees it is a good idea. I don't remember where though.
Re: Why hide a trusted function as safe?
On 26/07/15 14:24, Adam D. Ruppe via Digitalmars-d-learn wrote: If the whole function is marked @trusted, the compiler doesn't try to check it at all - it just takes your word for it. There was a bit of argument about this a while ago in bugzilla, not everyone agrees it is a good idea. I don't remember where though. If I recall right, the argument wasn't over the principle of trying to isolate the @trusted bits, but that @trusted was being used only to wrap up the particular function call that was technically triggering @system stuff, rather than the entirety of what actually needed to be trusted. I can't remember a good example off the top of my head, but no doubt the stuff is there in the bugzilla reports ;-)
Re: Why hide a trusted function as safe?
I remember doing something like that in druntime because of objects - you can't override @safe method prototype with @trusted one.
Re: Why hide a trusted function as safe?
Am Sun, 26 Jul 2015 13:11:51 + schrieb "Dicebot" : > I remember doing something like that in druntime because of > objects - you can't override @safe method prototype with @trusted > one. > That's probably related to the fact that safe and trusted functions have different mangled names. This also means that going from trusted to safe later on causes ABI breakage.
Re: GC stats
On Saturday, 25 July 2015 at 17:43:44 UTC, Martin Nowak wrote: On Saturday, 25 July 2015 at 17:34:26 UTC, Márcio Martins wrote: What I want is a clean non-intrusive way to log when a collection happened, how long my threads were stopped, how much total memory and how many blocks were recovered. i.e. how much garbage was created in between collections. Are there any hooks on the runtime? http://dlang.org/changelog.html#gc-options https://github.com/D-Programming-Language/druntime/blob/1e25749cd01ad08dc08319a3853fbe86356c3e62/src/rt/config.d#L14 I thought there is a recently added compiler option that profiles the GC and creates a report now?
Re: GC stats
On Sunday, 26 July 2015 at 14:16:46 UTC, Gary Willoughby wrote: On Saturday, 25 July 2015 at 17:43:44 UTC, Martin Nowak wrote: On Saturday, 25 July 2015 at 17:34:26 UTC, Márcio Martins wrote: What I want is a clean non-intrusive way to log when a collection happened, how long my threads were stopped, how much total memory and how many blocks were recovered. i.e. how much garbage was created in between collections. Are there any hooks on the runtime? http://dlang.org/changelog.html#gc-options https://github.com/D-Programming-Language/druntime/blob/1e25749cd01ad08dc08319a3853fbe86356c3e62/src/rt/config.d#L14 I thought there is a recently added compiler option that profiles the GC and creates a report now? Should be included in 2.068 I think: https://github.com/D-Programming-Language/druntime/blob/1e25749cd01ad08dc08319a3853fbe86356c3e62/src/rt/profilegc.d#L3
Re: static linking
On Sunday, 26 July 2015 at 05:22:14 UTC, Martin Nowak wrote: On Saturday, 25 July 2015 at 18:02:48 UTC, Laeeth Isharc wrote: I am trying to compile a D binary to run on AWS lambda. If I cannot link statically, which files should I include in the zip upload - libphobos2.so, libdruntime-linux64so.o ? I think dicebot who maitains the arch linux package change dmd to dynamically link with phobos by default (we don't yet do that on any other platform). You should be able to link statically using -L-l:libphobos2.a or -defaultlib=libphobos2.a. Thanks, Martin. I appreciate your time. I guess I was mixing up two things - total static linking so the executable doesn't depend on normal libraries, versus static linking with phobos and friends only. The former is trickier on arch in particular (not related to Dicebot's choice) because they don't distributed static versions of library files as a matter of policy. But it's really the latter that I would need to do, and I think what you suggest will do the job. How do I do the same on gdc and ldc ? Since running times may be a matter of seconds, speed and startup time counts especially for lambda. Probably starting via nodejs is an unnecessary tax, but I guess they will get rid of that requirement in time.
Re: static linking
On 07/26/2015 05:19 PM, Laeeth Isharc wrote: > > How do I do the same on gdc and ldc ? Since running times may be a > matter of seconds, speed and startup time counts especially for lambda. > Probably starting via nodejs is an unnecessary tax, but I guess they > will get rid of that requirement in time. AFAIK only ldc supports a dynamic phobos library ATM, and it shouldn't be default. But in both cases -L-l:libphobos2.a should do the job, though I think it's called libgphobos2.a for gdc and libphobos2-ldc.a for ldc.
Re: static linking
On 07/26/2015 05:19 PM, Laeeth Isharc wrote: > The former is trickier on arch in particular (not related to Dicebot's > choice) because they don't distributed static versions of library files > as a matter of policy. Yes, quite a few distributions no longer support fully static linking. Some, e.g. hardened gentoo, don't allow it for security reasons (they use ASLR on PIE).
Re: GC stats
On 07/26/2015 04:16 PM, Gary Willoughby wrote: > > I thought there is a recently added compiler option that profiles the GC > and creates a report now? That's an allocation profiler, the other one mentioned by me reports GC stats as requested by the OP.
Where can i find examples of multi-threaded fibers?
In the description for Fiber in std.thread is the following[1]: "Please note that there is no requirement that a fiber be bound to one specific thread. Rather, fibers may be freely passed between threads so long as they are not currently executing." How would this be accomplished and are there any code examples available to learn from? I'm assuming this would require a custom scheduler similar to the one in std.concurrency?[2] [1]: http://dlang.org/phobos/core_thread.html#.Fiber [2]: http://dlang.org/phobos/std_concurrency.html#.FiberScheduler
[Rosettacode] sum of powers conjecture
I've translated the C++ entry to D as third D entry, but it's not a good translation, I've just converted iterators to pointers instead of using ranges (the resulting speed is acceptable). You're welcome to improve it: http://rosettacode.org/wiki/Euler%27s_sum_of_powers_conjecture#Third_version Bye, bearophile
Re: [Rosettacode] sum of powers conjecture
On Sunday, 26 July 2015 at 18:40:59 UTC, bearophile wrote: I've translated the C++ entry to D as third D entry, but it's not a good translation, I've just converted iterators to pointers instead of using ranges (the resulting speed is acceptable). You're welcome to improve it: http://rosettacode.org/wiki/Euler%27s_sum_of_powers_conjecture#Third_version Bye, bearophile Bear, welcome back! You and all your inspirational ideas have been missed! Good to see you.
Re: Where can i find examples of multi-threaded fibers?
On 07/26/2015 11:07 AM, Gary Willoughby wrote:> In the description for Fiber in std.thread is the following[1]: > > "Please note that there is no requirement that a fiber be bound to one > specific thread. Rather, fibers may be freely passed between threads so > long as they are not currently executing." > > How would this be accomplished and are there any code examples available > to learn from? I'm assuming this would require a custom scheduler > similar to the one in std.concurrency?[2] > > [1]: http://dlang.org/phobos/core_thread.html#.Fiber > [2]: http://dlang.org/phobos/std_concurrency.html#.FiberScheduler It should be as simple as sending the fiber object between threads (including casting to-and-from shared when needed). I used std.concurrency.Generator[1][2] below instead of a naked Fiber as it is much more cleaner. main() uses the fiber then passes it to its worker and continues using it again: import std.stdio; import std.range; import std.algorithm; import std.concurrency; import core.thread; void fiberFunction() { 10.iota.each!(i => yield(i)); } void threadFunction() { auto fiber = cast()receiveOnly!(shared(Generator!int)); writefln("Produced in worker: %(%s %)", fiber.take(5)); } void main() { auto numbers = new Generator!int(&fiberFunction); auto worker = spawn(&threadFunction); writefln("Produced in main : %(%s %)", numbers.take(2)); worker.send(cast(shared)numbers); thread_joinAll(); writefln("Produced in main : %(%s %)", numbers); } Here is the output: Produced in main : 0 1 Produced in worker: 2 3 4 5 6 Produced in main : 7 8 9 Ali [1] http://dlang.org/phobos/std_concurrency.html#.Generator [2] http://ddili.org/ders/d.en/fibers.html#ix_fibers.Generator,%20std.concurrency
Re: Where can i find examples of multi-threaded fibers?
On Sunday, 26 July 2015 at 19:51:08 UTC, Ali Çehreli wrote: On 07/26/2015 11:07 AM, Gary Willoughby wrote:> In the Thanks for the example. I'll study it.
Re: static linking
On Sunday, July 26, 2015 19:17:59 Martin Nowak via Digitalmars-d-learn wrote: > On 07/26/2015 05:19 PM, Laeeth Isharc wrote: > > The former is trickier on arch in particular (not related to Dicebot's > > choice) because they don't distributed static versions of library files > > as a matter of policy. > > Yes, quite a few distributions no longer support fully static linking. > Some, e.g. hardened gentoo, don't allow it for security reasons (they > use ASLR on PIE). As I understand, it's considered a _very_ bad idea to statically link to glibc at this point, which sucks, since having a program that just keeps working when other stuff on the system is updated can be nice. It _is_ a security problem on some level though - particularly with stuff like openssl - since if you statically link, you don't get updates when the libraries you depend on get security fixes. But it's definitely statically linking everything that doesn't work with dmd (or at least didn't the last time I checked), because it doesn't pass -static through to gcc properly. Statically linking phobos should work just fine. - Jonathan M Davis