Thin delegate adapter
Dmitry Olshansky
dmitry.olsh at gmail.com
Wed Jan 12 23:30:33 PST 2011
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.olsh at gmail.com <mailto:dmitry.olsh at 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.olsh at gmail.com <mailto:dmitry.olsh at gmail.com>
> <mailto:dmitry.olsh at gmail.com <mailto:dmitry.olsh at 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
More information about the Digitalmars-d
mailing list