<div class="gmail_quote">On Mon, Oct 17, 2011 at 3:43 PM, Michel Fortin <span dir="ltr"><<a href="mailto:michel.fortin@michelf.com">michel.fortin@michelf.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div><div></div><div class="h5">On 2011-10-17 20:33:59 +0000, Andrew Wiley <<a href="mailto:wiley.andrew.j@gmail.com" target="_blank">wiley.andrew.j@gmail.com</a>> said:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Okay, I realize there have been some discussions about this, but I have a<br>
few questions about shared delegates because right now they are definitely<br>
broken, but I'm not sure how.<br>
Take this code example:<br>
<br>
synchronized class Thing {<br>
        void doSomeWork(void delegate() work) {<br>
                work();<br>
        }<br>
        void work() {}<br>
}<br>
<br>
void main() {<br>
        auto th = new Thing();<br>
        th.doSomeWork(&th.work);<br>
}<br>
<br>
This doesn't compile because the type of "&th.work" is "void delegate()<br>
shared", which cannot be cast implicitly to "void delegate()".<br>
My first question would be whether that type is correct. It's true that the<br>
data pointer of the delegate points to a shared object, but given that the<br>
function locks it, does that really matter in this case? I guess I'm just<br>
not clear on the exact meaning of "shared" in general, but it seems like<br>
whether the data is shared or not is irrelevant when the delegate points to<br>
a public member of a synchronized class. If it was a delegate pointing to a<br>
private/protected member (which should be illegal in this case), that would<br>
not be true.<br>
If that type is correct, the problem is that "void delegate() shared"<br>
doesn't parse as a type (there is a workaround because you can create<br>
variables of this type through alias and typeof).<br>
<br>
What, exactly, is wrong here?<br>
</blockquote>
<br></div></div>
I think what's wrong is that a shared delegate should implicitly convert to a non-shared one. The delegate is shared since it can be called safely from any thread, and making it non-shared only prevent you from propagating it to more thread so it's not harmful in any way.<br>

<font color="#888888">
<br></font></blockquote><div><br></div><div>Actually, I've been thinking about this some more, and I think that the delegate should only implicitly convert if the argument types are safe to share across threads as well.</div>

<div>If I had a class that looked like this:</div><div>synchronized class Thing2 {<br>       void doSomeWork(int i) {}</div><div>       void doSomeOtherWork(Thing2 t) {}<br>       void work() {}<br>}<br><br></div><div>The actual argument type in doSomeOtherWork is required to be shared(Thing2) (which isn't a problem here because Thing2 is a synchronized class, but you see the point).</div>

<div>These same rules should apply to shared delegates. I'm not sure exactly how this works for value types because they're always safe to pass as arguments yet shared(int) clearly isn't the same as int, but the rules will be the same for delegates as for member functions.</div>

<div><br></div><div>With that in mind, I'm not sure exactly how the implicit conversions should work, but the argument types should always be properly share-able.</div><div> </div></div><br>