Threads & Message Passing - Best practices ?

2017-09-11 Thread Jonas Mminnberg via Digitalmars-d
I am using the recommended message passing threading model for my 
project, and it is not always clear how to do things in the best 
way;


1. receive() pattern matching -- what is common here, always send 
(int, someData) where int is a value you compare to. Or create 
dummy types that you can match on directly?


  receive(int cmd, int[] data) { if(cmd == SomeCommand) 
doStuff(data); }

  receive(SomeCommand, int[] data) { doStuff(data); }

The latter seems nicer, but what's the best way to define those 
types?


Or maybe it's better to be even more general?  Something like;

receive(void delegate(ARGS) f, ARGS a) { f(a); }


2. What is the reason you can't decide which thread(s) to 
receive() from and is there any way around it? Right now I need 
to have a static updateAll() method that is aware of all 
instances and call update() on them as needed. Also it's very 
hard to have generic modules that has their own threads because 
they can receive messages from other modules threads...


3. Is there a recommended way to deal with creating immutable 
data ? Right now I just cast to immutable before returning the 
data since I know I have the only reference, but it would be nice 
to have something like a `UniqueReference` containing a 
immutableMove() method...





Re: Static inline field initialization

2017-08-22 Thread Jonas Mminnberg via Digitalmars-d

On Tuesday, 22 August 2017 at 12:20:45 UTC, Moritz Maxeiner wrote:



I agree that it can be confusing if you try to read it with C++ 
semantics [1]; the solution, however, imho is not to change D 
semantics or throw warnings [2], but to refer to the D spec 
[3], which states that static initialization of class members 
is used instead of default initialization (before any 
constructors are run). To me that means a statically 
initialized class field shall have the same value in all class 
instances, i.e. it's not silent sharing, you explicitly 
requested the sharing. If that doesn't mean the same to others, 
the D spec wording should be updated to be clearer on the 
subject.
If you don't want instances to share a field value, instead of 
static initialization you can use constructor initialization 
[4]:



class Test
{
ubyte[] buf;
this()
{
buf = new ubyte[1000];
}
 }

void main()
{
auto a = new Test();
auto b = new Test();
assert(a.buf.ptr != b.buf.ptr);
}


I know that it is according to the standard but since D has gone 
out of it's way to make sure sharing doesn't occur otherwise, by 
defaulting to TLS storage etc, I feel this breaks the "no 
surprises" rule. I took me a long time to find this out and when 
I mentioned it to other casual D programmers they also had no 
idea this was how it worked.






Static inline field initialization

2017-08-22 Thread Jonas Mminnberg via Digitalmars-d
Because of D's static initialization of members, this assert 
fails:


class Test {
ubyte[] buf = new ubyte[1000];
}

void main() {
auto a = new Test();
auto b = new Test();
assert(a.buf.ptr != b.buf.ptr);
}

This is bad, since;
* It is not how C++ works
* It introduces silent sharing of data
* It's usually not what you want

Shouldn't this at least generate a warning, or ideally not be 
allowed?