digitalmars.D - Suggestion: Change precedence of 'new'
- Bill Baxter (20/20) Apr 09 2008 Sometimes it's handy to invoke a function on a class right after
- Unknown W. Brackets (8/39) Apr 09 2008 I think the problem is in supporting this syntax:
- Robert Fraser (6/16) Apr 09 2008 The argument (as far as I can tell) is that it would be supported only
- Bill Baxter (15/23) Apr 09 2008 That makes sense. So the rule would be that 'new' munches all the
- Georg Wrede (2/32) Apr 10 2008 Just to clarify, how would that look with the proposed precedence?
- Bill Baxter (12/45) Apr 10 2008 You mean what does it look like in java? Like this:
- Georg Wrede (8/61) Apr 10 2008 So, you gain the omission of one pair of parentheses, but lose in
- Robert Fraser (5/30) Apr 10 2008 I don't think that particular example is very difficult to read without
- Lionello Lunesu (7/16) Apr 09 2008 In C# the first one works, too.
- bearophile (8/11) Apr 10 2008 The syntax of the new operator can be improved.
- Georg Wrede (3/17) Apr 10 2008 New vanishes in the foliage.
- bearophile (5/8) Apr 10 2008 I see. Well, I presume Ruby people don't have much problems with that sy...
- Georg Wrede (6/15) Apr 10 2008 :-)
- Jason House (3/31) Apr 10 2008 Why would anyone write code like that in D? First of all a delegate wor...
- Robert Fraser (22/54) Apr 10 2008 Okay, how about this (admittedly contrived) example?
- Jason House (2/61) Apr 10 2008 Actually, I meant in the context of the original proposal new foo().bar
- Bill Baxter (10/43) Apr 10 2008 Yeh, sorry. It wasn't meant to be a convincing argument about why the
- Ary Borenszweig (40/50) Apr 11 2008 It's just because you can ommit the parenthesis in case the constructor
- Robert Fraser (4/6) Apr 11 2008 OT, why does Eclipse do this? It was also required where I used to work
- Ary Borenszweig (18/25) Apr 11 2008 These are just guesses:
- Scott S. McCoy (15/17) Apr 11 2008 At the same time, the fact that parenthesis are optional is also quite
- Simen Kjaeraas (21/41) Apr 11 2008 =
- Bill Baxter (7/62) Apr 11 2008 No. I'm not going to start writing constructors for every class twice
Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put parentheses around the new expression because it has lower precedence than dotExpression: (new Thread(&func)).run(); I don't recall how it works in C++, but at least in Java, the first version works. I'm not a grammar guru, so can anyone who is say whether the above change would be possible? Maybe it would muck up construction based on fully qualified names? So that new thread.Thread(&func) would have to become new (thread.Thread(&func) If so that would suck. But Java is able to make it work somehow, and the construct seems to be used quite heavily there (I've been looking at a lot of SWT code lately...) --bb
Apr 09 2008
I think the problem is in supporting this syntax: auto x = new package.module.Class; In which case, differing it from this is difficult: auto y = new package.module.Class.propertyMethod; Anyway, I believe the docs say that it is always an error to rely on order of operations... perhaps I'm wrong. -[Unknown] Bill Baxter wrote:Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put parentheses around the new expression because it has lower precedence than dotExpression: (new Thread(&func)).run(); I don't recall how it works in C++, but at least in Java, the first version works. I'm not a grammar guru, so can anyone who is say whether the above change would be possible? Maybe it would muck up construction based on fully qualified names? So that new thread.Thread(&func) would have to become new (thread.Thread(&func) If so that would suck. But Java is able to make it work somehow, and the construct seems to be used quite heavily there (I've been looking at a lot of SWT code lately...) --bb
Apr 09 2008
Unknown W. Brackets wrote:I think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".In which case, differing it from this is difficult: auto y = new package.module.Class.propertyMethod; Anyway, I believe the docs say that it is always an error to rely on order of operations... perhaps I'm wrong.Not if the order is well defined, just when two operators have the same precedence. 2 + 5 * 3 should always evaluate to 17, never to 21.-[Unknown]
Apr 09 2008
Robert Fraser wrote:Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary. --bbI think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 09 2008
Bill Baxter wrote:Robert Fraser wrote:Just to clarify, how would that look with the proposed precedence?Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary.I think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Georg Wrede wrote:Bill Baxter wrote:You mean what does it look like in java? Like this: new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }.run(); (it's creating an anonymous subclass of 'Runnable', and running it.) --bbRobert Fraser wrote:Just to clarify, how would that look with the proposed precedence?Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary.I think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Bill Baxter wrote:Georg Wrede wrote:So, you gain the omission of one pair of parentheses, but lose in expressional clarity. In the current version, it is very clear to the reader (even to the one not familiar with the particular usage) what is going on. With the proposal, one has to really think hard, if one is not familiar with it from before. That's always a bad sign. I'm not absolutely against this, but some more compelling examples would go a long way.Bill Baxter wrote:You mean what does it look like in java? Like this: new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }.run(); (it's creating an anonymous subclass of 'Runnable', and running it.)Robert Fraser wrote:Just to clarify, how would that look with the proposed precedence?Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary.I think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Georg Wrede wrote:I don't think that particular example is very difficult to read without the parentheses, but a new anonymous class expression is actually a different type of expression than a new expression, so now we're talking changing the precedence of two expressions.So, you gain the omission of one pair of parentheses, but lose in expressional clarity. In the current version, it is very clear to the reader (even to the one not familiar with the particular usage) what is going on. With the proposal, one has to really think hard, if one is not familiar with it from before. That's always a bad sign. I'm not absolutely against this, but some more compelling examples would go a long way.Just to clarify, how would that look with the proposed precedence?You mean what does it look like in java? Like this: new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }.run(); (it's creating an anonymous subclass of 'Runnable', and running it.)
Apr 10 2008
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:ftjqml$2oo4$1 digitalmars.com...Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put parentheses around the new expression because it has lower precedence than dotExpression: (new Thread(&func)).run(); I don't recall how it works in C++, but at least in Java, the first version works.In D, "new" already has higher precedence than "cast", which is more useful, IMHO: #Foo foo = cast(Foo)new Bar; L.
Apr 09 2008
Bill Baxter Wrote:Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run();The syntax of the new operator can be improved. Here Python syntax can't be used (in Python the () operator of the *class* object creates the object instance. In Python classes are objects of a metaclass). Ruby uses a syntax similar to this, and I think it may be fit for D too, solving your problem (that I share with you): Thread(&func).new.run(); Do you see problems with this syntax? Bye, bearophile
Apr 10 2008
bearophile wrote:Bill Baxter Wrote:New vanishes in the foliage. I think it is important that new is easy to spot when reading code.Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run();The syntax of the new operator can be improved. Here Python syntax can't be used (in Python the () operator of the *class* object creates the object instance. In Python classes are objects of a metaclass). Ruby uses a syntax similar to this, and I think it may be fit for D too, solving your problem (that I share with you): Thread(&func).new.run(); Do you see problems with this syntax?
Apr 10 2008
Georg Wrede:I see. Well, I presume Ruby people don't have much problems with that syntax. And I think you can set your editor/IDE to show that 'new' in red color ;-) Bye, bearophileDo you see problems with this syntax?New vanishes in the foliage. I think it is important that new is easy to spot when reading code.
Apr 10 2008
bearophile wrote:Georg Wrede::-) But then there are textbooks, normal source code listings on paper, uncolored source code on web pages and blogs, source files viewed with other than a D-aware text reader or editor, etc... Oh, and this NG too.I see. Well, I presume Ruby people don't have much problems with that syntax. And I think you can set your editor/IDE to show that 'new' in red color ;-)Do you see problems with this syntax?New vanishes in the foliage. I think it is important that new is easy to spot when reading code.
Apr 10 2008
Bill Baxter Wrote:Robert Fraser wrote:Why would anyone write code like that in D? First of all a delegate works just as well as a class with one member. Second, if this is simply run like a blocking function call, why not define a nested function and just call it? PS: I'm not trying to knock down your feature request. I just find the example strange. I'm sure there's more useful examples available and you just picked one at random.Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary. --bbI think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Jason House wrote:Bill Baxter Wrote:Okay, how about this (admittedly contrived) example? public abstract class A { public final int foo() { // do stuff bar(); // do more stuff & return something } protected abstract void bar(); } void baz() { int k = new class A { protected void bar() { // ... } }.foo(); }Robert Fraser wrote:Why would anyone write code like that in D? First of all a delegate works just as well as a class with one member. Second, if this is simply run like a blocking function call, why not define a nested function and just call it? PS: I'm not trying to knock down your feature request. I just find the example strange. I'm sure there's more useful examples available and you just picked one at random.Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary. --bbI think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Robert Fraser Wrote:Jason House wrote:Actually, I meant in the context of the original proposal new foo().barBill Baxter Wrote:Okay, how about this (admittedly contrived) example? public abstract class A { public final int foo() { // do stuff bar(); // do more stuff & return something } protected abstract void bar(); } void baz() { int k = new class A { protected void bar() { // ... } }.foo(); }Robert Fraser wrote:Why would anyone write code like that in D? First of all a delegate works just as well as a class with one member. Second, if this is simply run like a blocking function call, why not define a nested function and just call it? PS: I'm not trying to knock down your feature request. I just find the example strange. I'm sure there's more useful examples available and you just picked one at random.Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary. --bbI think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Jason House wrote:Bill Baxter Wrote:Yeh, sorry. It wasn't meant to be a convincing argument about why the features is needed. It was just some SWT Java code I happened to be porting yesterday, so it was more just to say "here's another thing that works without parens in the Java way". Unless you're porting Java code, I hope no one does write D code like that. :-) But I have wanted to do things like new Widget(args).enabled = false; --bbRobert Fraser wrote:Why would anyone write code like that in D? First of all a delegate works just as well as a class with one member. Second, if this is simply run like a blocking function call, why not define a nested function and just call it? PS: I'm not trying to knock down your feature request. I just find the example strange. I'm sure there's more useful examples available and you just picked one at random.Unknown W. Brackets wrote:That makes sense. So the rule would be that 'new' munches all the dot-separated identifiers to its right till it hits something besides a dot or an identifier. Here's another one from actual D code ported from Java: (new class Runnable { public void run() { if (canvas.isDisposed()) return; render(); canvas.swapBuffers(); canvas.getDisplay().timerExec(15, this); } }).run(); In Java the parens around that whole mess aren't necessary. --bbI think the problem is in supporting this syntax: auto x = new package.module.Class;The argument (as far as I can tell) is that it would be supported only if trailing parentheses were supplied, so that expression would have to be written as "new package.module.Class().propertyMethod;".
Apr 10 2008
Bill Baxter escribió:Sometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put parentheses around the new expression because it has lower precedence than dotExpression: (new Thread(&func)).run();It's just because you can ommit the parenthesis in case the constructor (or any function) has no arguments, like new Thread.run Nice, huh? You save yourself a pair of parenthesis, but... --- module one; import std.stdio; class One { int foo; this() { foo = 1; } static class Two { int foo; this() { foo = 2; } } } void main() { auto x = new One.Two; writefln("%s", x.foo); // 1 or 2? :-) } --- I really like how Java handles this: parenthesis are mandatory for methods and constructors. Then you can have things like this: class Foo { int property: void property(int p) { property = p; } } Foo.property --> the variable Foo.property() --> the method In C++ and D, you have to use _property, or fProperty, mProperty, or some other ugly syntax. :(
Apr 11 2008
Ary Borenszweig wrote:In C++ and D, you have to use _property, or fProperty, mProperty, or some other ugly syntax. :(OT, why does Eclipse do this? It was also required where I used to work (mName for member variables, sName for static variables), but I never asked why.
Apr 11 2008
Robert Fraser escribió:Ary Borenszweig wrote:These are just guesses: - When you want to autocomplete a field, you type "f" instead of "this." - You never mistake a parameter from a field. But I don't like it. :-P I know, Eclipse colorizes these differently, but it seems the Eclipse guys don't want to assume other developers are using/seeing their code with Eclipse. That's also why, I think, in inherited functions you see: /* * (non-Javadoc) * see foo.Bar.method(String, int) */ public void method(String s, int i) { // ... } In Eclispe you get the marker saying that method is being overriden, but if you open it in a simple text editor, you can't immediately know that. Well... that was until annotations appear, together with Override.In C++ and D, you have to use _property, or fProperty, mProperty, or some other ugly syntax. :(OT, why does Eclipse do this? It was also required where I used to work (mName for member variables, sName for static variables), but I never asked why.
Apr 11 2008
At the same time, the fact that parenthesis are optional is also quite nice. It allows accessing a member to magically become accessing an accessor, and it eliminates unnecessary parenthesis on multiple statements which makes trees nicer to access, consider DOM: document.firstChild.firstChild.lastChild.parentNode; This is a lot nicer than.... document.getFirstChild().getFirstChild().getLastChild().getParentNode(); To make the example less extreme, it's still nicer than: document.firstChild().firstChild().lastChild().parentNode() and less ugly. But, it's not really a trade off that matters much in the long run. Cheers, Scott S. McCoy On Fri, 2008-04-11 at 13:46 -0300, Ary Borenszweig wrote:I really like how Java handles this: parenthesis are mandatory for methods and constructors.
Apr 11 2008
On Thu, 10 Apr 2008 03:32:01 +0200, Bill Baxter = <dnewsgroup billbaxter.com> wrote:Sometimes it's handy to invoke a function on a class right after =creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put =parentheses around the new expression because it has lower precedence ==than dotExpression: (new Thread(&func)).run(); I don't recall how it works in C++, but at least in Java, the first =version works. I'm not a grammar guru, so can anyone who is say whether the above =change would be possible? Maybe it would muck up construction based on fully qualified names? =So =that new thread.Thread(&func) would have to become new (thread.Thread(&func) If so that would suck. But Java is able to make it work somehow, and ==the construct seems to be used quite heavily there (I've been looking =at =a lot of SWT code lately...) --bbYou can work around this with static opCalls. class foo { static foo opCall() { return new foo(); } int bar() { return 4; } } int a =3D foo().bar; Still requires a parentheses, but you might like it better. -- Simen
Apr 11 2008
Simen Kjaeraas wrote:On Thu, 10 Apr 2008 03:32:01 +0200, Bill Baxter <dnewsgroup billbaxter.com> wrote:No. I'm not going to start writing constructors for every class twice just to be able to save on some parenthesis in certain situations. If making "new foo().bar" work is going to have any undesirable side effects than it's not worth it. It just seemed to me that it might be a simple change to the grammar. --bbSometimes it's handy to invoke a function on a class right after creating it: new Thread(&func).run(); Unfortunately that doesn't work in D right now. You have to put parentheses around the new expression because it has lower precedence than dotExpression: (new Thread(&func)).run(); I don't recall how it works in C++, but at least in Java, the first version works. I'm not a grammar guru, so can anyone who is say whether the above change would be possible? Maybe it would muck up construction based on fully qualified names? So that new thread.Thread(&func) would have to become new (thread.Thread(&func) If so that would suck. But Java is able to make it work somehow, and the construct seems to be used quite heavily there (I've been looking at a lot of SWT code lately...) --bbYou can work around this with static opCalls. class foo { static foo opCall() { return new foo(); } int bar() { return 4; } } int a = foo().bar; Still requires a parentheses, but you might like it better.
Apr 11 2008