Re: Thin delegate adapter
On Thu, Jan 13, 2011 at 5:30 AM, Dmitry Olshansky dmitry.o...@gmail.comwrote: On 13.01.2011 2:16, Guilherme Vieira wrote: No sh*t..?! @__@ That's so cool! But is it smart enough to know the stack frame doesn't need to go to heap in this case? (since it returns a heap object referecing another heap object, i.e. can it untangle `b' from the stack?) Ehm, it can optimize certain cases but for the moment it doesn't. Still, it needs to store b somewhere, right? and delegate is 2 pointers in fact, so b should go on heap anyway. So it narrows down to if it can save only parts of the stack frame ... Since it only uses something the size of a pointer (`b'), it might as well do some trickery and use `b' as `this' and turn the delegate into (Switch.State state) { this.toggled = cast(bool)(state); } (or something of similar effect). -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira
Thin delegate adapter
Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State.OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira
Re: Thin delegate adapter
On Wed, Jan 12, 2011 at 10:41 AM, Guilherme Vieira n2.nitro...@gmail.comwrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State.OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira Oops, missed the template itself: template adapt(alias fun, Arg) { auto adapt(Object)(Object obj) { auto adaptImpl = new AdaptImpl!(fun, Object)(obj); return adaptImpl.opCall!(Arg); } } class AdaptImpl(alias fun, Object) { this(Object obj) { this.obj = obj; } auto opCall(Arg)(Arg a) { return binaryFun!(fun, a, obj)(a, obj); } private Object obj; } -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira
Re: Thin delegate adapter
On 12.01.2011 15:41, Guilherme Vieira wrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State..OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira How is it better then built-in language feature? This works just fine: void main() { //they can't be scope and compiler enforces this (+ scope is deprecated) //actually, the orignal code is unsafe - what hapens if adapted delegate escapes current scope? auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State a){ b.toggled = cast(bool)a; }; s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } -- Dmitry Olshansky
Re: Thin delegate adapter
Ah, I totally missed that. But what if `s' went out of the scope and the scope ended? Wouldn't the scope reference (the one containing `b') be lost and cause memory corruption? E.g.: Switch make_switch() { auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State state) { b.toggled = cast(bool)(state); }; return s; } -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 10:57 AM, Dmitry Olshansky dmitry.o...@gmail.comwrote: On 12.01.2011 15:41, Guilherme Vieira wrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State..OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira How is it better then built-in language feature? This works just fine: void main() { //they can't be scope and compiler enforces this (+ scope is deprecated) //actually, the orignal code is unsafe - what hapens if adapted delegate escapes current scope? auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State a){ b.toggled = cast(bool)a; }; s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } -- Dmitry Olshansky
Re: Thin delegate adapter
On 12.01.2011 16:07, Guilherme Vieira wrote: Ah, I totally missed that. But what if `s' went out of the scope and the scope ended? Wouldn't the scope reference (the one containing `b') be lost and cause memory corruption? E.g.: Switch make_switch() { auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State state) { b.toggled = cast(bool)(state); }; return s; } That's the main point of built-in delegates - the compiler detects them and places the enclosing stack frame on heap, so it's all sort of cool magic that just works :) -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 10:57 AM, Dmitry Olshansky dmitry.o...@gmail.com mailto:dmitry.o...@gmail.com wrote: On 12.01.2011 15:41, Guilherme Vieira wrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State..OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira How is it better then built-in language feature? This works just fine: void main() { //they can't be scope and compiler enforces this (+ scope is deprecated) //actually, the orignal code is unsafe - what hapens if adapted delegate escapes current scope? auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State a){ b.toggled = cast(bool)a; }; s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } -- Dmitry Olshansky -- Dmitry Olshansky
Re: Thin delegate adapter
No sh*t..?! @__@ That's so cool! But is it smart enough to know the stack frame doesn't need to go to heap in this case? (since it returns a heap object referecing another heap object, i.e. can it untangle `b' from the stack?) -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 11:49 AM, Dmitry Olshansky dmitry.o...@gmail.comwrote: On 12.01.2011 16:07, Guilherme Vieira wrote: Ah, I totally missed that. But what if `s' went out of the scope and the scope ended? Wouldn't the scope reference (the one containing `b') be lost and cause memory corruption? E.g.: Switch make_switch() { auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State state) { b.toggled = cast(bool)(state); }; return s; } That's the main point of built-in delegates - the compiler detects them and places the enclosing stack frame on heap, so it's all sort of cool magic that just works :) -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 10:57 AM, Dmitry Olshansky dmitry.o...@gmail.commailto: dmitry.o...@gmail.com wrote: On 12.01.2011 15:41, Guilherme Vieira wrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State..OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira How is it better then built-in language feature? This works just fine: void main() { //they can't be scope and compiler enforces this (+ scope is deprecated) //actually, the orignal code is unsafe - what hapens if adapted delegate escapes current scope? auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State a){ b.toggled = cast(bool)a; }; s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } -- Dmitry Olshansky -- Dmitry Olshansky
Re: Thin delegate adapter
On 13.01.2011 2:16, Guilherme Vieira wrote: No sh*t..?! @__@ That's so cool! But is it smart enough to know the stack frame doesn't need to go to heap in this case? (since it returns a heap object referecing another heap object, i.e. can it untangle `b' from the stack?) Ehm, it can optimize certain cases but for the moment it doesn't. Still, it needs to store b somewhere, right? and delegate is 2 pointers in fact, so b should go on heap anyway. So it narrows down to if it can save only parts of the stack frame ... -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 11:49 AM, Dmitry Olshansky dmitry.o...@gmail.com mailto:dmitry.o...@gmail.com wrote: On 12.01.2011 16:07, Guilherme Vieira wrote: Ah, I totally missed that. But what if `s' went out of the scope and the scope ended? Wouldn't the scope reference (the one containing `b') be lost and cause memory corruption? E.g.: Switch make_switch() { auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State state) { b.toggled = cast(bool)(state); }; return s; } That's the main point of built-in delegates - the compiler detects them and places the enclosing stack frame on heap, so it's all sort of cool magic that just works :) -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Wed, Jan 12, 2011 at 10:57 AM, Dmitry Olshansky dmitry.o...@gmail.com mailto:dmitry.o...@gmail.com mailto:dmitry.o...@gmail.com mailto:dmitry.o...@gmail.com wrote: On 12.01.2011 15:41, Guilherme Vieira wrote: Hi, I'm wondering if a delegate adapter template like isn't handy for Phobos (it may be especially useful for std.signal): class Switch { enum State { ON, OFF } void trigger() { switch (mState) { case State.ON: mState = State..OFF; break; case State.OFF: mState = State.ON; break; default: break; } if (watch !is null) watch(mState); } void delegate(State s) watch; private State mState; } class ToggleButton { @property toggled(bool toggled) { writeln(ToggleButton.toggled(, toggled, )); } } void main() { scope s = new Switch(); scope b = new ToggleButton(); s.watch = b.toggled; // error: invalid conversion s.watch = adapt!(obj.toggled = cast(bool)(a), Switch.State)(b); s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } Yes, it urges to be polished. Particularly, it doesn't support multiple arguments. I also wanted to place the argument type tuple somwhere else (actually wanted to hide it completely, but I think that's not possible). Feedback? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira How is it better then built-in language feature? This works just fine: void main() { //they can't be scope and compiler enforces this (+ scope is deprecated) //actually, the orignal code is unsafe - what hapens if adapted delegate escapes current scope? auto s = new Switch(); auto b = new ToggleButton(); s.watch = (Switch.State a){ b.toggled = cast(bool)a; }; s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` s.trigger(); // prints `ToggleButton.toggled(true)` s.trigger(); // prints `ToggleButton.toggled(false)` } -- Dmitry Olshansky -- Dmitry Olshansky -- Dmitry Olshansky