digitalmars.D - Suggestion: Change precedence of 'new'
- Bill Baxter <dnewsgroup billbaxter.com> Apr 09 2008
- "Unknown W. Brackets" <unknown simplemachines.org> Apr 09 2008
- Robert Fraser <fraserofthenight gmail.com> Apr 09 2008
- Bill Baxter <dnewsgroup billbaxter.com> Apr 09 2008
- Georg Wrede <georg nospam.org> Apr 10 2008
- Bill Baxter <dnewsgroup billbaxter.com> Apr 10 2008
- Georg Wrede <georg nospam.org> Apr 10 2008
- Robert Fraser <fraserofthenight gmail.com> Apr 10 2008
- "Lionello Lunesu" <lionello lunesu.remove.com> Apr 09 2008
- bearophile <bearophileHUGS lycos.com> Apr 10 2008
- Georg Wrede <georg nospam.org> Apr 10 2008
- bearophile <bearophileHUGS lycos.com> Apr 10 2008
- Georg Wrede <georg nospam.org> Apr 10 2008
- Ary Borenszweig <ary esperanto.org.ar> Apr 11 2008
- Robert Fraser <fraserofthenight gmail.com> Apr 11 2008
- Ary Borenszweig <ary esperanto.org.ar> Apr 11 2008
- "Scott S. McCoy" <tag cpan.org> Apr 11 2008
- "Simen Kjaeraas" <simen.kjaras gmail.com> Apr 11 2008
- Bill Baxter <dnewsgroup billbaxter.com> Apr 11 2008
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: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;".
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. --bb
Apr 09 2008
Bill Baxter wrote:Robert Fraser wrote: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;".
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.
Just to clarify, how would that look with the proposed precedence?
Apr 10 2008
Georg Wrede wrote:Bill Baxter wrote:Robert Fraser wrote: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;".
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.
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.) --bb
Apr 10 2008
Bill Baxter wrote:Georg Wrede wrote:Bill Baxter wrote:Robert Fraser wrote: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;".
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.
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.)
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.
Apr 10 2008
Georg Wrede wrote: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.)
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.
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.
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 C# the first one works, too. 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: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?
New vanishes in the foliage. I think it is important that new is easy to spot when reading code.
Apr 10 2008
Georg Wrede:Do you see problems with this syntax?
I think it is important that new is easy to spot when reading code.
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, bearophile
Apr 10 2008
bearophile wrote:Georg Wrede: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.
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 ;-)
:-) 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.
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: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.
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.
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? =
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 =
a lot of SWT code lately...) --bb
You 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: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
You 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.
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. --bb
Apr 11 2008









Robert Fraser <fraserofthenight gmail.com> 