Immutable Message Passing

Andrew Wiley wiley.andrew.j at gmail.com
Sun Dec 4 14:16:49 PST 2011


On Sun, Dec 4, 2011 at 2:46 PM, Andrew Wiley <wiley.andrew.j at gmail.com> wrote:
> On Sun, Dec 4, 2011 at 1:42 AM, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
>> On Sunday, December 04, 2011 01:24:02 Andrew Wiley wrote:
>>> This should work, right? I'm not just going crazy or something?
>>>
>>> import std.concurrency;
>>> import std.stdio;
>>>
>>> class Bob {
>>> }
>>>
>>> void main() {
>>>     auto tid = spawn(&b);
>>>     tid.send(new immutable(Bob)());
>>> }
>>>
>>> void b() {
>>>     receive(
>>>         (immutable(Bob) b) {
>>>             writeln("got it");
>>>         }
>>>     );
>>> }
>>>
>>>
>>> I'm getting this from both GDC (trunk) and DMD (2.056 and trunk - I
>>> can't seem to get 2.055 to run):
>>> core.exception.AssertError@/usr/include/d/std/variant.d(286): immutable(Bob)
>>>
>>> Seems like some type conversion isn't working properly and variant is
>>> flagging immutable types as not assignable?
>>
>> Well, that particular assertion seems to be because of the immutability. It
>> seems that Variant can't handle it - the comment with it being
>>
>> // type is not assignable
>>
>> But I'd have to go digging to see why on earth this is failing (and that's
>> assuming that it's not a compiler bug, since then it would be completely out
>> of my league). It _looks_ like it should work.
>>
>> - Jonathan M Davis
>
> Actually, it looks like I am going crazy. I went back to dmd 2.052
> (and every version in between), and this doesn't seem to have ever
> worked.
> However, not allowing message passing with immutable messages
> eliminates one of the main use cases for immutable. I'll see if I can
> find a workaround.
>
> The actual issue is that once Variant finds a matching type, it tries
> to assign `immutable(Bob) = immutable(Bob)` , which is illegal.
> However, all it needs to do is assign a *reference* to an immutable
> object. Unfortunately, we don't support that.
> Incidentally, this makes a compelling argument for something like
> immutable(Object) ref.

So it looks like right now, message passing is copying objects, which
seems very bad. Check this out:
--------
import std.stdio;
import std.concurrency;

class Bob {
}

void main() {
	auto tid = spawn(&func);
	auto bob = new shared(Bob)();
	writeln("bob is currently at ", cast(void*)(&bob));
	tid.send(bob);
}

void func() {
	receive(
		(shared(Bob) bob) {
			writeln("now it's at: ", cast(void*)(&bob));
		}
	);
}
--------
This results in output like:
--------
bob is currently at 18FE44
now it's at: 29DFE30
--------

Which seems to imply that my object was copied, which clearly was not
what I wanted. If I put the reference into an array, it copies the
array struct and you wind up with a reference to the same object, but
if I pass in a reference to a shared object, it copies the object.
This doesn't seem to be the correct way to handle reference types to me.


More information about the Digitalmars-d mailing list