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