Re: Avoiding __traits(getAttributes, ...) on alias
Vlad Levenfeld: > but beware I've noticed that sometimes this is not > equivalent to the previous version and I'm not sure how or why that happens. > In particular I notice that > > mixin("const bool value = "~expr~";)"); > and > const bool value = mixin(expr); > > are not the same, for some reason. What are the differences?
Kìtchèń Desìgners Hertfordsìre
Kìtchèń Desìgners Hertfordsìre. Thirty €x Display K ìtcheńs To Clear. W W W . è x d ì S p l a y K ì t C H è ń S 1 . c o . u k £ 595 EAch wIth appliańcès.
Re: why can't I call const methods on shared objects?
aaand on further experimentation it turns out I don't need a template at all, I can just overload it... strange, I seem to remember not being able to do that before.
Re: why can't I call const methods on shared objects?
PS After reading your post I experimented with overloading shared/unshared methods in my code and came up with this solution: shared Id!Service id ()() const if (is (typeof(this) == shared)) { return (cast(Service)this).id; } Id!Service id () const { return service_id; } I like this better than casting at the callsite (though it would be nice to roll those two into one method using a static if somehow, but I can't think of any way to do this).
Re: Avoiding __traits(getAttributes, ...) on alias
I've recently found out that you can deal with the abundance of backticks and escapes in a couple of ways: q{ your code here... } will resolve to a string but your editor can still highlight it as D code, making it more readable. also, turning things like: mixin ("if ("~expr~")") into: if (mixin(expr)) can improve readability but beware I've noticed that sometimes this is not equivalent to the previous version and I'm not sure how or why that happens. In particular I notice that mixin("const bool value = "~expr~";)"); and const bool value = mixin(expr); are not the same, for some reason.
Re: core.sync.rwmutex example
On 05/09/2014 02:51 PM, Joshua Niehus via Digitalmars-d-learn wrote: Hi Charles, would the following work (just a shot in the dark) ? //--- module test; import std.stdio; import std.concurrency; void spawnedFuncFoo(Tid tid, Tid tidBar) { receive( (int i) { writeln("Foo Received the number ", i); send(tidBar, i, thisTid); auto barSuccessful = receiveOnly!(string); writeln("Bar got my (Foo) message"); } ); send(tid, true); } void spawnedFuncBar(Tid tid) { receive( (int i, Tid tidFoo) { writeln("Foo passed me (Bar) the number ", i); send(tidFoo, "done"); } ); receive( (string sig) { writeln("Main says I'm (Bar) done."); send(tid, 42); } ); } void main() { auto tidBar = spawn(&spawnedFuncBar, thisTid); auto tidFoo = spawn(&spawnedFuncFoo, thisTid, tidBar); send(tidFoo, 42); auto fooWasSuccessful = receiveOnly!(bool); assert(fooWasSuccessful); send(tidBar, "your done"); auto barWasSuccessful = receiveOnly!(int); assert(barWasSuccessful == 42); writeln("Successfully had two separate threads communicate with each other"); } //--- Thank you very much for the response. How do you ensure that the received message (in "auto barWasSuccessful = receiveOnly!(int); ") came from the thread sent to by tidFoo? Also, why two receives in spawnedFuncBar? I thought that receive handled multiple different arguments with a single receive? Are you asserting that the arguments happen in sequence, as it appears? That doesn't look as if it would scale will to multiple threads. And with multiple threads I would expect the mailbox to start getting very full with inappropriate messages that never got handled, because they came at the wrong time (and arguably from the wrong sender, as it seems that there is an assumption that there is no intervening thread sending any messages). That's why I was looking for a way to ensure that the message being received came from the appropriate sender. You can't depend on messages to always come from the source you expect. This probably means that you need to have only ONE receive statement, located in a loop. And some way to check and set the status of incoming messages. Also a yield method that lets one receive and stack any incoming messages during a busy cycle, though I think that that's what receive does. OTOH, I do note that you are using "auto barWasSuccessful = receiveOnly!(int);" which implies that the value returned is not a void, even though you never use the result. This fits with the claims of TDPL, but make me increasingly dubious about the documentation. Or do I just not understand what a function of type void is supposed to return? The hashtable itself will be a uint64_t[string] which is confined to one thread, so the access methods need to be rather straightforwards. I'm thinking of: receive ( (string s, uint64_t id) { void set(s, id); } (string s) { void get(s); } (Variant v) { void reportError (v); } ); get should send the id back to the calling thread. set updates the AA and sends true or false (success) back to the calling thread. But doesn't this design lock the entire hashtable while the update is in progress? Is there a better way? set will be, approx: void set (string s, uint64_t id) {tbl[s]=id; send (tid, true); } etc. But I'm worried about the receiving end. It needs, somehow, to ensure that the message it receives is the appropriate message, and that other messages don't get dropped while it's waiting for the answer...or, perhaps worse, substituted for the expected answer. If I can depend on msg[0] of "auto msg = receiveOnly!(Tid, bool)" that will allow me to check that the message was received from the proper source Also, if a message is received that if of an inappropriate form, an exception is thrown. Recovery looks problematic. But this is a case that should be expected when different threads are sending messages. And if the message is of the correct form, but from the wrong thread, how can one re-queue it for later processing? So far the best idea I've got is to have a dequeue of messages that are stacked with "receiveOnly!Variant". But this would need to be accesses in various places throughout the thread, and the handling looks messy. OTOH, it does let me save messages that come in at the wrong time where I can deal with them later. So it's not all bad. But it gives up on the processing that receive makes available. And note that this processing doesn't need to be done in the hashtable function, that's pretty clear, but wherever it's used. Which is terrible. As it is, I might be better putting the hashtable in s synchronized class. The entire hashtable is getting locked o
Recommendation on option parsing
Phobos' std.getopt is a bit spare for my taste, as there is no builtin general help facility with word-wrapping. Does anyone have a recommendation on which of the existing command line option parsing libraries floating around in the wild to use? If it doesn't compile against the current version of phobos I'm willing to put in a little work, but since I'm very new to D I probably would not make the best design decisions. -- Chris
Re: why can't I call const methods on shared objects?
Let me see if I understand this right... let's say I have some (unshared) class that launches threads to do its real work in. class Foo { this () {thread = spawn (&work);} shared void work () {...}; void send_message (T) (T msg) {thread.send (msg);} Tid thread; } It has an unshared method to pass messages to the worker thread, and everything is copacetic, but what is the best practice for when I want another thread to interact with one of these instances? class Bar { this () {thread = spawn (&pass);} shared void pass () { receive ( (shared Foo F) {this.F = F;} // (1) (T msg) {(cast(Foo)F).send_message (msg);}, // (2) ); void send_message (T) (T msg) {thread.send (msg);} Tid thread; Foo F; } void main () { auto F = new Foo; auto B = new Bar; B.send_message (cast(shared)F);// (3) // sleep } When I interact with F from at (1), this.F is automatically shared (because Bar is shared) so this compiles. Here, this.F refers to the same F I would refer to if I accessed this.F from the main method, it just gets automatically shared whenever Bar is shared. So when I spawn a worker thread, the worker thread sees a shared Bar (and shared F), while the main thread sees a Bar that it owns, but they are both looking at the same Bar (just with different access rules, like a const and non-const reference to the same object). At (2), I have to cast F to unshared in order to send it a message. But this is ok, because I am only sending messages, and am not risking a race condition. Basically I am announcing "I know that multiple threads can see this, but I am taking ownership of it and taking responsiblity for preventing races." And when I cast to shared at (3), I am announcing "I am explicitly recognizing that multiple threads may now access this, and that there is a potential for races." Is this the right way to handle this situation? And on a more general note, the shared keyword, as I understand it, is intended to be a sort of compiler-reinforced tag that I can use to prevent races the same way const helps prevent unintended side-effects, and to aid my reasoning when I do need to debug a race?
Re: Improving IO Speed
Try this; import std.mmfile; scope mmFile = new MmFile("T201212A.IDX"); TaqIdx* arr = cast(TaqIdx*)mmFile[0..mmFile.length].ptr; for (ulong i = 0; i < mmFile.length/TaqIdx.sizeof; ++i) { // do something... writeln(arr[i].symbol); } On Friday, 14 March 2014 at 18:00:58 UTC, TJB wrote: I have a program in C++ that I am translating to D as a way to investigate and learn D. The program is used to process potentially hundreds of TB's of financial transactions data so it is crucial that it be performant. Right now the C++ version is orders of magnitude faster. Here is a simple example of what I am doing in D: import std.stdio : writefln; import std.stream; align(1) struct TaqIdx { align(1) char[10] symbol; align(1) int tdate; align(1) int begrec; align(1) int endrec; } void main() { auto input = new File("T201212A.IDX"); TaqIdx tmp; int count; while(!input.eof()) { input.readExact(&tmp, TaqIdx.sizeof); // Do something with the data } } Do you have any suggestions for improving the speed in this situation? Thank you! TJB
Re: CMake for D
On Friday, 9 May 2014 at 21:43:04 UTC, Trent Forkert wrote: The way I've tackled that in my (still work-in-progress) CMake fork[1] is to add an `include_directories(TEXT ...)` signature. I like that, it seems clean. Unfortunately, you'll need to build my CMake from source, though that isn't difficult. Also, while I am hopeful about The standard CMake build instructions just don't work on the CentOS 6.5 systems we are currently using at work. I gave up after 2 hours. Since CMakeD2 is working for me I'm sticking with it for now but... getting my changes merged upstream, there is no guarantee of that, so proceed with caution. ... it would be great to have better D support in CMake, I really hope your changes do get committed upstream. I plan on using D somewhat quitely for about a year and after I've worked out the gotcha's start talking to my programming friends. An upstream merge would get used. Do note that my CMake work is independent of CMakeD2 and its forks. See my project wiki for more info. [1] https://github.com/trentforkert/cmake Thanks, I'll check it out. -- Chris
Re: why can't I call const methods on shared objects?
On Fri, 09 May 2014 17:45:37 -0400, Vlad Levenfeld wrote: Is there any way to declare a method as "safe regardless of shared/mutability/etc" (or some other way to avoid cast(Type)object.property every time I want to check a property which won't affect any state)? Not really for shared. For everything else, there's const for value properties, and inout for reference properties. Shared is quite different, because the method has to be cognizant of race conditions. It has to be implemented differently. Casting away shared is somewhat dangerous, but OK if you logically know there is no race condition. -Steve
Re: why can't I call const methods on shared objects?
I mean I thought that's what "pure" was for but the compiler complains all the same.
Re: core.sync.rwmutex example
Hi Charles, would the following work (just a shot in the dark) ? //--- module test; import std.stdio; import std.concurrency; void spawnedFuncFoo(Tid tid, Tid tidBar) { receive( (int i) { writeln("Foo Received the number ", i); send(tidBar, i, thisTid); auto barSuccessful = receiveOnly!(string); writeln("Bar got my (Foo) message"); } ); send(tid, true); } void spawnedFuncBar(Tid tid) { receive( (int i, Tid tidFoo) { writeln("Foo passed me (Bar) the number ", i); send(tidFoo, "done"); } ); receive( (string sig) { writeln("Main says I'm (Bar) done."); send(tid, 42); } ); } void main() { auto tidBar = spawn(&spawnedFuncBar, thisTid); auto tidFoo = spawn(&spawnedFuncFoo, thisTid, tidBar); send(tidFoo, 42); auto fooWasSuccessful = receiveOnly!(bool); assert(fooWasSuccessful); send(tidBar, "your done"); auto barWasSuccessful = receiveOnly!(int); assert(barWasSuccessful == 42); writeln("Successfully had two separate threads communicate with each other"); } //---
Re: why can't I call const methods on shared objects?
Is there any way to declare a method as "safe regardless of shared/mutability/etc" (or some other way to avoid cast(Type)object.property every time I want to check a property which won't affect any state)?
Re: why can't I call const methods on shared objects?
Is this still the case if the method is const or pure?
Re: why can't I call const methods on shared objects?
On Fri, 09 May 2014 17:37:35 -0400, Vlad Levenfeld wrote: Error: non-shared const method is not callable using a shared mutable object Why not? If the method is const, it can't modify the object anyway. Non-shared methods cannot be called on shared objects. Otherwise, you could have unintended race conditions. -Steve
Re: CMake for D
On Friday, 9 May 2014 at 21:11:54 UTC, Chris Piker wrote: On Monday, 24 March 2014 at 23:55:14 UTC, Dragos Carp wrote: I moved cmaked2 to github [1], updated and simplified the usage a little (system cmake patch not necessary anymore). You can give it a try. Dub registry support is also on the way. Dragos What is the best way to specify a mixin include directory for dmd under CMake? I can arbitarily add a -J option to the compiler flags but should the cmake-d module include a variable that should be set? -- Chris The way I've tackled that in my (still work-in-progress) CMake fork[1] is to add an `include_directories(TEXT ...)` signature. Unfortunately, you'll need to build my CMake from source, though that isn't difficult. Also, while I am hopeful about getting my changes merged upstream, there is no guarantee of that, so proceed with caution. Do note that my CMake work is independent of CMakeD2 and its forks. See my project wiki for more info. - Trent [1] https://github.com/trentforkert/cmake
why can't I call const methods on shared objects?
Error: non-shared const method is not callable using a shared mutable object Why not? If the method is const, it can't modify the object anyway.
Re: CMake for D
On Monday, 24 March 2014 at 23:55:14 UTC, Dragos Carp wrote: I moved cmaked2 to github [1], updated and simplified the usage a little (system cmake patch not necessary anymore). You can give it a try. Dub registry support is also on the way. Dragos What is the best way to specify a mixin include directory for dmd under CMake? I can arbitarily add a -J option to the compiler flags but should the cmake-d module include a variable that should be set? -- Chris
core.sync.rwmutex example
The example code from core.sync.rwmutex seems bugged. After copying it I added an import for core.sync.rwmutex, and moved the executions of runTest into...well: void main() {runTest(ReadWriteMutex.Policy.PREFER_READERS); runTest(ReadWriteMutex.Policy.PREFER_WRITERS); } Then I tried to compile it. I got the following error messages: test3.d(36): Error: class core.sync.rwmutex.ReadWriteMutex member m_commonMutex is not accessible test3.d(38): Error: class core.sync.rwmutex.ReadWriteMutex member m_numQueuedReaders is not accessible test3.d(39): Error: class core.sync.rwmutex.ReadWriteMutex member m_numQueuedWriters is not accessible Checking out the documentation, I don't see that they SHOULD be accessible, so I think the compiler's correct, and the example is wrong. P.S.: Does anyone have a good working example of rwmutex? I'm trying to build a hash table that is write accessible from one thread, and readable from anywhere, and this looked like the best way to do it...except that when I start to figure out how to use it I get errors. Also does anyone have any examples of two directional communication between two particular threads (a bit more than just yes/no) in the presence of multiple other threads, so that when a thread asks another for information, only that other thread is allowed to reply? Perhaps that's a better way to implement the shared-read hash table. (I'd like to use std.concurrency, but I can't figure out how one is supposed to manage specific inter-thread communications.) -- Charles Hixson
Re: sort struct of arrays
On Friday, 9 May 2014 at 16:26:22 UTC, Rene Zwanenburg wrote: On Friday, 9 May 2014 at 15:52:51 UTC, John Colvin wrote: On Friday, 9 May 2014 at 14:23:41 UTC, Luís Marques wrote: If you have an array of structs, such as... struct Foo { int x; int y; } Foo[] foos; ...and you wanted to sort the foos then you'd do something like... foos.sort!(a.x < b.x), ..and, of course, both of the fields x and y get sorted together. If you have a so-called struct of arrays, or an equivalent situation, such as... int[] fooX; int[] fooY; ...is there a simple way to sort fooX and fooY "together"/coherently (keyed on, say, fooX), using the standard lib? For some situations (expensive/impossible to move/copy elements of fooY), you would be best with this: auto indices = zip(iota(fooX.length).array, fooX).sort!"a[1] < b[1]".map!"a[0]"; auto sortedFooY = fooY.indexed(indices); bearing in mind that this causes an allocation for the index, but if you really can't move the elements of fooY (and fooX isn't already indices of fooY) then you don't have much of a choice. It's probably better to use makeIndex: http://dlang.org/phobos/std_algorithm.html#makeIndex good call, I didn't realise that existed.
Re: sort struct of arrays
On Friday, 9 May 2014 at 15:52:51 UTC, John Colvin wrote: On Friday, 9 May 2014 at 14:23:41 UTC, Luís Marques wrote: If you have an array of structs, such as... struct Foo { int x; int y; } Foo[] foos; ...and you wanted to sort the foos then you'd do something like... foos.sort!(a.x < b.x), ..and, of course, both of the fields x and y get sorted together. If you have a so-called struct of arrays, or an equivalent situation, such as... int[] fooX; int[] fooY; ...is there a simple way to sort fooX and fooY "together"/coherently (keyed on, say, fooX), using the standard lib? For some situations (expensive/impossible to move/copy elements of fooY), you would be best with this: auto indices = zip(iota(fooX.length).array, fooX).sort!"a[1] < b[1]".map!"a[0]"; auto sortedFooY = fooY.indexed(indices); bearing in mind that this causes an allocation for the index, but if you really can't move the elements of fooY (and fooX isn't already indices of fooY) then you don't have much of a choice. It's probably better to use makeIndex: http://dlang.org/phobos/std_algorithm.html#makeIndex
Re: Any chance to avoid monitor field in my class?
flamencofantasy, thanx for that! Where do we vote here? =)
Re: Any chance to avoid monitor field in my class?
On Friday, 9 May 2014 at 14:56:21 UTC, flamencofantasy wrote: One thing I hate about C# (which is what I use professionally) is the sync block index in every single class instance. Why not have the developer decide when he needs a Monitor and manually use it?! I am disappointed D took the same route. If it can be changed without breaking existing code, you might be able to convince people to make it somehow optional or elided when unnecessary.
Re: sort struct of arrays
On Friday, 9 May 2014 at 14:23:41 UTC, Luís Marques wrote: If you have an array of structs, such as... struct Foo { int x; int y; } Foo[] foos; ...and you wanted to sort the foos then you'd do something like... foos.sort!(a.x < b.x), ..and, of course, both of the fields x and y get sorted together. If you have a so-called struct of arrays, or an equivalent situation, such as... int[] fooX; int[] fooY; ...is there a simple way to sort fooX and fooY "together"/coherently (keyed on, say, fooX), using the standard lib? For some situations (expensive/impossible to move/copy elements of fooY), you would be best with this: auto indices = zip(iota(fooX.length).array, fooX).sort!"a[1] < b[1]".map!"a[0]"; auto sortedFooY = fooY.indexed(indices); bearing in mind that this causes an allocation for the index, but if you really can't move the elements of fooY (and fooX isn't already indices of fooY) then you don't have much of a choice.
Re: sort struct of arrays
On Friday, 9 May 2014 at 14:48:50 UTC, anonymous wrote: std.range.zip(fooX, fooY).sort!((a, b) => a[0] < b[0]); I wasn't sure if that's supposed to work. Turns out the documentation on zip [1] has this exact use case as an example. [1] http://dlang.org/phobos/std_range.html#zip Ha! Awesome! Sorry that I missed that example.
Re: Any chance to avoid monitor field in my class?
One thing I hate about C# (which is what I use professionally) is the sync block index in every single class instance. Why not have the developer decide when he needs a Monitor and manually use it?! I am disappointed D took the same route.
Re: sort struct of arrays
On Friday, 9 May 2014 at 14:23:41 UTC, Luís Marques wrote: If you have an array of structs, such as... struct Foo { int x; int y; } Foo[] foos; ...and you wanted to sort the foos then you'd do something like... foos.sort!(a.x < b.x), ..and, of course, both of the fields x and y get sorted together. If you have a so-called struct of arrays, or an equivalent situation, such as... int[] fooX; int[] fooY; ...is there a simple way to sort fooX and fooY "together"/coherently (keyed on, say, fooX), using the standard lib? std.range.zip(fooX, fooY).sort!((a, b) => a[0] < b[0]); I wasn't sure if that's supposed to work. Turns out the documentation on zip [1] has this exact use case as an example. [1] http://dlang.org/phobos/std_range.html#zip
sort struct of arrays
If you have an array of structs, such as... struct Foo { int x; int y; } Foo[] foos; ...and you wanted to sort the foos then you'd do something like... foos.sort!(a.x < b.x), ..and, of course, both of the fields x and y get sorted together. If you have a so-called struct of arrays, or an equivalent situation, such as... int[] fooX; int[] fooY; ...is there a simple way to sort fooX and fooY "together"/coherently (keyed on, say, fooX), using the standard lib?
Re: Down the VisualD0.3.38-1.exe ,found virus!
Trend Micro and Comodo have (from my limited experience) been pretty good about dealing with false positives, so does anyone want to inform them and the others as well? On 5/8/14, sigod via Digitalmars-d-learn wrote: > On Friday, 9 May 2014 at 01:02:39 UTC, FrankLike wrote: >> Hi,everyone, >> down VisulaD from >> http://rainers.github.io/visuald/visuald/StartPage.html >> found the virus:Win32.Troj.Undef.(kcloud) >> >> Why? >> >> Frank > > https://www.virustotal.com/en/file/bbd76ddb41a80f0526f6cf1e37a2db2736cfa8f29ed3f5fd7a4336bf4c8bbe43/analysis/ > > Just 5 of 52. Probably a false alarm. >
Re: Avoiding __traits(getAttributes, ...) on alias
On Friday, 9 May 2014 at 12:19:12 UTC, John Colvin wrote: On Friday, 9 May 2014 at 11:53:59 UTC, Stefan Frijters wrote: I've been playing with UDAs a bit and I wanted to find all variables with a particular attribute in various modules. I thought I had it cracked, until I added a module that contains an alias declaration, which makes it choke when trying to execute __traits(getAttributes, ...). A small example is shown below. Is there any conditional I can insert between the two foreach lines to make it detect such an alias declaration, and move on to the next derived member? Or should getAttributes handle this by just returning no attributes? import std.traits; @("testattr") int foo; alias char[256] MyChar; @("testattr") int bar; void main() { foreach(e ; __traits(derivedMembers, mixin(__MODULE__))) { foreach( t; __traits(getAttributes, mixin(e)) ){ pragma(msg, t); } } // testattr // test.d(9): Error: first argument is not a symbol // test.d(9): Error: invalid foreach aggregate false // testattr } Any hints would be appreciated! Kind regards, Stefan Frijters You could always do a static if with __traits(compiles, __traits(getAttributes, mixin(e)) Thank you for the fast reply; this solves my problem. I actually tried this before, but in my actual code instead of the example, where I'm deep into backticks and quotes and escaped quotes so I probably made a mistake there...
Re: Avoiding __traits(getAttributes, ...) on alias
On Friday, 9 May 2014 at 11:53:59 UTC, Stefan Frijters wrote: I've been playing with UDAs a bit and I wanted to find all variables with a particular attribute in various modules. I thought I had it cracked, until I added a module that contains an alias declaration, which makes it choke when trying to execute __traits(getAttributes, ...). A small example is shown below. Is there any conditional I can insert between the two foreach lines to make it detect such an alias declaration, and move on to the next derived member? Or should getAttributes handle this by just returning no attributes? import std.traits; @("testattr") int foo; alias char[256] MyChar; @("testattr") int bar; void main() { foreach(e ; __traits(derivedMembers, mixin(__MODULE__))) { foreach( t; __traits(getAttributes, mixin(e)) ){ pragma(msg, t); } } // testattr // test.d(9): Error: first argument is not a symbol // test.d(9): Error: invalid foreach aggregate false // testattr } Any hints would be appreciated! Kind regards, Stefan Frijters You could always do a static if with __traits(compiles, __traits(getAttributes, mixin(e))
Avoiding __traits(getAttributes, ...) on alias
I've been playing with UDAs a bit and I wanted to find all variables with a particular attribute in various modules. I thought I had it cracked, until I added a module that contains an alias declaration, which makes it choke when trying to execute __traits(getAttributes, ...). A small example is shown below. Is there any conditional I can insert between the two foreach lines to make it detect such an alias declaration, and move on to the next derived member? Or should getAttributes handle this by just returning no attributes? import std.traits; @("testattr") int foo; alias char[256] MyChar; @("testattr") int bar; void main() { foreach(e ; __traits(derivedMembers, mixin(__MODULE__))) { foreach( t; __traits(getAttributes, mixin(e)) ){ pragma(msg, t); } } // testattr // test.d(9): Error: first argument is not a symbol // test.d(9): Error: invalid foreach aggregate false // testattr } Any hints would be appreciated! Kind regards, Stefan Frijters
Re: Any chance to avoid monitor field in my class?
Imho, offtop, also i'm a C++/Obj-C guy and that might partially explain my preferences, but here are some more reasons: 1. I like the concept of CT-reflection and CTFE a lot. This makes metaprogramming extremely powerful without any RT overheads. It brings a lot more control to what goes to RT. I guess D still needs to shrink it's runtime a bit more, and __monitors is just another example of that. 2. It's extremely easy for C++/C#/Java/Objc-C developers to switch to D without loosing any bit of their productivity, but gaining lots of possibilities, that can be used in future. And C++/C#/Java/Obj-C is the majority of the world now. Even PHP developers should think of D one day =). 3. That's the most arguable, but D's syntax and semantics looks much cleaner and uniform to me than Rust's.
Re: Any chance to avoid monitor field in my class?
Yuriy: but I like D, and i strongly believe it's the next big language. Oh, good. Do you want to briefly explain why? :) Bye, bearophile