digitalmars.D - Neat trick - 'with' and unnamed objects + 'with' proposals
- Bill Baxter (40/40) Apr 23 2007 I just discovered this little trick that I think is way cool.
- Denis Golovan (1/5) Apr 24 2007
- Bill Baxter (4/9) Apr 24 2007 You say "is" as if it exists in some other language that you've used?
- Max Samukha (6/15) Apr 24 2007 Object initializers in C# 3.0 seem to do a similar thing but they
- eao197 (64/71) Apr 24 2007 e a
- Dan (31/78) Apr 24 2007 In JavaScript they've had this "feature" for a very long time. I never,...
- Bill Baxter (8/39) Apr 24 2007 You seem to be harping on 'with' in general, not with what I was
- BCS (8/62) Apr 24 2007 how about take a trick from "if"
- Bill Baxter (7/16) Apr 24 2007 Yeh, I was actually just thinking that myself, and was disappointed to
- BCS (2/25) Apr 24 2007 Ohhh. That would be nice in switch ... and while...
- Bill Baxter (11/37) Apr 24 2007 I was thinking 'while' would have issues, because the condition is
- Max Samukha (7/44) Apr 24 2007 This would be inconsistent with if(), which declares the variable to
- Max Samukha (14/60) Apr 24 2007 BTW, there is a bug
- Bill Baxter (3/67) Apr 24 2007 You mean it should be an error according to the specs, right?
- Max Samukha (3/70) Apr 24 2007 Yes
- Bill Baxter (9/52) Apr 24 2007 No that's not what I meant. Note the extra block scope _outside_ the
- Max Samukha (14/66) Apr 24 2007 I understand now. But in your second proposal you want the object to
- Dan (5/10) Apr 24 2007 Which is frighteningly different semantically, while being almost identi...
- BCS (17/35) Apr 24 2007 if(x = 3) doesn't compile. For the If case the syntax requiters that the...
I just discovered this little trick that I think is way cool. You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable. with(new someGUIWidget(myParent)) { shown = true; focusable = false; } That's really nifty for GUI code. This could be even more useful if there were some kind of 'this' for 'with' blocks. Then you could also call non-member functions. with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); } Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed: with(new someGUIWidget(myParent)) { some_global_function(with); } And even cooler would be if you could have a 'with-expression' that just evaluates to the thing in the parens: auto obj = with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); }; Sometimes I've seen people try to make APIs in C++ where all the attribute setters return the object so that property setting can be chained, like: myObject.set_focusable(true).set_shown(true); Presumably the objective is to avoid repeating the name of the object a lot. But that never works out too well, because making every mutator return a pointer to 'this' is just not so practical in the end, and forcing every property setting operation to use function call syntax is also not so great. --bb
Apr 23 2007
Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:+1. That feature is useful sometimes.--bb
Apr 24 2007
Denis Golovan wrote:You say "is" as if it exists in some other language that you've used? Does it? And if so what's the syntax? --bbOr perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:+1. That feature is useful sometimes.
Apr 24 2007
On Tue, 24 Apr 2007 22:03:07 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:Denis Golovan wrote:don't provide a way to call global (and local, I guess) functions with 'this'. http://community.bartdesmet.net/blogs/bart/archive/2006/12/04/C_2300_-3.0-Feature-Focus-_2D00_-Part-2-_2D00_-Object-Initializers.aspxYou say "is" as if it exists in some other language that you've used? Does it? And if so what's the syntax? --bbOr perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed:+1. That feature is useful sometimes.
Apr 24 2007
On Tue, 24 Apr 2007 17:03:07 +0400, Bill Baxter = <dnewsgroup billbaxter.com> wrote:Denis Golovan wrote:e aOr perhaps analogous to how constructors are called 'this()' and hav='this' pointer, we'd have a 'with' pointer so that the meaning of ==You say "is" as if it exists in some other language that you've used? ='this' in a class wouldn't be shadowed:+1. That feature is useful sometimes.Does it? And if so what's the syntax?Such behaviour can easily be implemented in Ruby. This is very simple = demonstration: class Demo attr_reader :shown attr_reader :focused end class AnotherDemo attr_reader :title end def some_global_function( obj ) p obj end def with( obj, &blk ) class <<obj def with; self; end end begin obj.instance_eval &blk ensure class <<obj remove_method( :with ) end end obj end d =3D with( Demo.new ) { shown =3D false focused =3D true some_global_function( with ) } a =3D with( AnotherDemo.new ) { title =3D 'Hello, World' some_global_function( with ) } That program prints: d: shown: false, focused: true a: title: Hello, World Such implementation of 'with' assumes that obj hasn't method 'with'. But= = this limitation can be removed via aliasing. -- = Regards, Yauheni Akhotnikau
Apr 24 2007
Bill Baxter Wrote:I just discovered this little trick that I think is way cool. You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable. with(new someGUIWidget(myParent)) { shown = true; focusable = false; }In JavaScript they've had this "feature" for a very long time. I never, ever use it. Why? x = 3; myFunc = function(){ x = 2; this.x = 1; bla bla bla ginger with(x){ bla bla bla bla ginger bla bla bla bla bla x += 3; bla bla } x -= 2; } That in itself isn't so bad. But in real code, it looks godawful and makes a guy concentrate on scoping it for a second; distracting him from the algorithm.That's really nifty for GUI code. This could be even more useful if there were some kind of 'this' for 'with' blocks. Then you could also call non-member functions.Lions and tigers and bears, oh my. Can't you just: alias supercalafragilisticexpialadocious.bob.mom.mom.niece.daughter d; d.shown = true; d.focusable = false; etc.?with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); } Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed: with(new someGUIWidget(myParent)) { some_global_function(with); }Eww... ambiguity and context sensitivity.And even cooler would be if you could have a 'with-expression' that just evaluates to the thing in the parens: auto obj = with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); };auto obj = new someGuiWidget(myParent){ shown = true; focusable = false; }; some_global_function(obj); <- can't execute in a class declaration. Try in the constructor?Sometimes I've seen people try to make APIs in C++ where all the attribute setters return the object so that property setting can be chained, like: myObject.set_focusable(true).set_shown(true);I did that back in the day too, but not for setting properties, it was for performing more complex algorithms with the DOM, such as making an object move in circles, or fall using a gravity formula.Presumably the objective is to avoid repeating the name of the object a lot. But that never works out too well, because making every mutator return a pointer to 'this' is just not so practical in the end, and forcing every property setting operation to use function call syntax is also not so great.Property setting operations? Totally agree. Returning a this* isn't so bad unless you have something else to return. I only did it with subroutines. The real reason it's bad is because you're masturbating the stack doing calls like that just to avoid doing something in source code. Such a thing is forgiveable in web scripts where filesize matters, it's not in programming.
Apr 24 2007
Dan wrote:Bill Baxter Wrote:You seem to be harping on 'with' in general, not with what I was actually talking about which is using it on unnamed variables. 'with' itself has been in D as long as I've known D, I just didn't realize you could use it with anonymous objects. Anyway, you certainly don't have to like it or use it. But I find it useful in moderation. --bbI just discovered this little trick that I think is way cool. You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable. with(new someGUIWidget(myParent)) { shown = true; focusable = false; }In JavaScript they've had this "feature" for a very long time. I never, ever use it. Why? x = 3; myFunc = function(){ x = 2; this.x = 1; bla bla bla ginger with(x){ bla bla bla bla ginger bla bla bla bla bla x += 3; bla bla } x -= 2; } That in itself isn't so bad. But in real code, it looks godawful and makes a guy concentrate on scoping it for a second; distracting him from the algorithm.
Apr 24 2007
Bill Baxter wrote:I just discovered this little trick that I think is way cool. You can use 'with' in combination with an anonymous object to set attributes on that object without having to bother giving it a name or a variable. with(new someGUIWidget(myParent)) { shown = true; focusable = false; } That's really nifty for GUI code. This could be even more useful if there were some kind of 'this' for 'with' blocks. Then you could also call non-member functions. with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); } Or perhaps analogous to how constructors are called 'this()' and have a 'this' pointer, we'd have a 'with' pointer so that the meaning of 'this' in a class wouldn't be shadowed: with(new someGUIWidget(myParent)) { some_global_function(with); } And even cooler would be if you could have a 'with-expression' that just evaluates to the thing in the parens: auto obj = with(new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(this); }; Sometimes I've seen people try to make APIs in C++ where all the attribute setters return the object so that property setting can be chained, like: myObject.set_focusable(true).set_shown(true); Presumably the objective is to avoid repeating the name of the object a lot. But that never works out too well, because making every mutator return a pointer to 'this' is just not so practical in the end, and forcing every property setting operation to use function call syntax is also not so great. --bbhow about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }
Apr 24 2007
BCS wrote:Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
Bill Baxter wrote:BCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
BCS wrote:Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
On Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:BCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
On Tue, 24 Apr 2007 20:18:24 +0300, Max Samukha <samukha voliacable.com> wrote:On Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:BTW, there is a bug void main(char[][] f) { int x = 1; if (auto x = 2) { writefln(x); } writefln(x); } x in if() shadows the outer x and it shouldn't according to the specsBCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
Max Samukha wrote:On Tue, 24 Apr 2007 20:18:24 +0300, Max Samukha <samukha voliacable.com> wrote:You mean it should be an error according to the specs, right? --bbOn Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:BTW, there is a bug void main(char[][] f) { int x = 1; if (auto x = 2) { writefln(x); } writefln(x); } x in if() shadows the outer x and it shouldn't according to the specsBCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
On Wed, 25 Apr 2007 02:38:26 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:Max Samukha wrote:YesOn Tue, 24 Apr 2007 20:18:24 +0300, Max Samukha <samukha voliacable.com> wrote:You mean it should be an error according to the specs, right? --bbOn Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:BTW, there is a bug void main(char[][] f) { int x = 1; if (auto x = 2) { writefln(x); } writefln(x); } x in if() shadows the outer x and it shouldn't according to the specsBCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
Max Samukha wrote:On Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:No that's not what I meant. Note the extra block scope _outside_ the while. That would be silently introduced by the transformation. The scope added is a scope that you have no way of interacting with or introducing code into, so effectively it *is* limiting the var scope to the scope of the while(). Of course there are no "scopes" anyway after everything gets compiled down to ASM, so its all just pleasant fictions to help us poor humans understand what's going on. --bbBCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
On Wed, 25 Apr 2007 02:35:02 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:Max Samukha wrote:I understand now. But in your second proposal you want the object to be accessible outside the 'with' block, so would it better to declare the variable outside the scope in the first place? with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); } name.shown = false;On Wed, 25 Apr 2007 01:53:56 +0900, Bill Baxter <dnewsgroup billbaxter.com> wrote:No that's not what I meant. Note the extra block scope _outside_ the while. That would be silently introduced by the transformation. The scope added is a scope that you have no way of interacting with or introducing code into, so effectively it *is* limiting the var scope to the scope of the while(). Of course there are no "scopes" anyway after everything gets compiled down to ASM, so its all just pleasant fictions to help us poor humans understand what's going on. --bbBCS wrote:This would be inconsistent with if(), which declares the variable to be local to if's scope. BTW, it'd be nice to have the variable declared outside the if block as you proposed for 'with'. I remember a case or two when I wanted that.Bill Baxter wrote:I was thinking 'while' would have issues, because the condition is evaluated multiple times. So I left it off the list. Maybe it's not a problem though. Just make it equiv to { typeof(condition()) x; while(x = condition()) { // do stuff } } --bbBCS wrote:Ohhh. That would be nice in switch ... and while...Bill Baxter wrote:how about take a trick from "if" with(auto name = new someGUIWidget(myParent)) { shown = true; focusable = false; some_global_function(name); }Yeh, I was actually just thinking that myself, and was disappointed to find out it doesn't work. :-( Looking at the spec it seems that's special to 'if'. It could be useful for switch(), with() and synchronized(), but it seems it hasn't been added. --bb
Apr 24 2007
Bill Baxter Wrote:typeof(condition()) x; while(x = condition()) { // do stuff } }Which is frighteningly different semantically, while being almost identical syntactically to: while(x == condition()) { Which is probably why Walter didn't want it to work. It concerns me a little that if(x = 3) works. Honestly, D is syntactically abstracted away enough that while(something something) wouldn't have to compile down to evaluating it repeatedly.
Apr 24 2007
Dan wrote:Bill Baxter Wrote:if(x = 3) doesn't compile. For the If case the syntax requiters that the type specifier be used: if(auto x = 3) // works if(x == 3) // works if(x = 3) // fails OTOH with 'wile' the third case is totally legitimate char x; while(x = getc()) // scan for null and use non null in loop; actually the proposed addition would make that error less likely, in fact the direct assignment could be banned in a while statement. char x; while(auto c = getc()) { x=c; // if last c needed; break; }typeof(condition()) x; while(x = condition()) { // do stuff } }Which is frighteningly different semantically, while being almost identical syntactically to: while(x == condition()) { Which is probably why Walter didn't want it to work. It concerns me a little that if(x = 3) works. Honestly, D is syntactically abstracted away enough that while(something something) wouldn't have to compile down to evaluating it repeatedly.
Apr 24 2007