www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Operator precedence of "new"

reply bearophile <bearophileHUGS lycos.com> writes:
Currently to call a method to a newly build object/struct you need:

(new Foo).bar();

But isn't it better to change the D operator precedence rules a bit and allow
new to bind more closely than the method call, to allow a syntax like:

new Foo.bar();

Do you see bad side effects in this D2 change?

Bye and thank you,
bearophile
Oct 15 2010
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 15 Oct 2010 16:12:24 +0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Currently to call a method to a newly build object/struct you need:

 (new Foo).bar();

 But isn't it better to change the D operator precedence rules a bit and  
 allow new to bind more closely than the method call, to allow a syntax  
 like:

 new Foo.bar();

 Do you see bad side effects in this D2 change?

 Bye and thank you,
 bearophile

Isn't this syntax used to instantiate inner class/struct, declared in Foo? The two are so much different there is really little point of sharing syntax for it.
Oct 15 2010
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2010-10-15 08:12:24 -0400, bearophile <bearophileHUGS lycos.com> said:

 Currently to call a method to a newly build object/struct you need:
 
 (new Foo).bar();
 
 But isn't it better to change the D operator precedence rules a bit and 
 allow new to bind more closely than the method call, to allow a syntax 
 like:
 
 new Foo.bar();
 
 Do you see bad side effects in this D2 change?

But then, how does that work? new Foo.SubType.bar(); Could work like this: new (Foo.Subtype).bar(); which doesn't look too bad as long as .bar() is at the end. Remove it and you'll get this: new (Foo.Subtype); Hardly interesting, and somewhat counter-intuitive. That's especially bad considering that all types are in reality enclosed module name which can be made explicit: new (std.stdio.File); I much prefer that this works: new std.stdio.File; new Foo.Subtype; Even if it means I have to do: (new Foo).bar(); -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 15 2010
prev sibling next sibling parent Stanislav Blinov <blinov loniir.ru> writes:
  15.10.2010 16:12, bearophile пишет:
 Currently to call a method to a newly build object/struct you need:

 (new Foo).bar();

 But isn't it better to change the D operator precedence rules a bit and allow
new to bind more closely than the method call, to allow a syntax like:

 new Foo.bar();

 Do you see bad side effects in this D2 change?

What if bar() is a static function of Foo? Current precedence allows the compiler to bug you if you write new Foo.bar(); If precedence is modified in the way you propose, then you effectively get a call to static function through an instance (which in itself is valid operation), though that instance is immediately thrown away.
Oct 15 2010
prev sibling next sibling parent Stanislav Blinov <blinov loniir.ru> writes:
  15.10.2010 17:07, Stanislav Blinov пишет:
  15.10.2010 16:12, bearophile пишет:
 Currently to call a method to a newly build object/struct you need:

 (new Foo).bar();

 But isn't it better to change the D operator precedence rules a bit 
 and allow new to bind more closely than the method call, to allow a 
 syntax like:

 new Foo.bar();

 Do you see bad side effects in this D2 change?

What if bar() is a static function of Foo? Current precedence allows the compiler to bug you if you write new Foo.bar(); If precedence is modified in the way you propose, then you effectively get a call to static function through an instance (which in itself is valid operation), though that instance is immediately thrown away.

Forgot to mention the 'bad' side: Despite you actually do throw instance away as a result of such call, in case of non-static method it is done intentionally and with keeping in mind precisely what does Foo's ctor do, while in case of static call instance construction may be unexpected and lead to subtle difficult-to-trace bugs.
Oct 15 2010
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Related: A nice alternative for quickly using anonymous objects is
using the with statement, e.g.:

with (new Foo)
{
    foo();
    // ... more code
}

And after the with block the object doesn't exist anymore. Or you
could bind it to some internal reference and keep it there, which
wouldn't destroy it after exiting the with block. Many of the DFL GUI
library code samples work this way, and it's quite a nice syntax imo.

On 10/15/10, Stanislav Blinov <blinov loniir.ru> wrote:
   15.10.2010 17:07, Stanislav Blinov =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
  15.10.2010 16:12, bearophile =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
 Currently to call a method to a newly build object/struct you need:

 (new Foo).bar();

 But isn't it better to change the D operator precedence rules a bit
 and allow new to bind more closely than the method call, to allow a
 syntax like:

 new Foo.bar();

 Do you see bad side effects in this D2 change?

What if bar() is a static function of Foo? Current precedence allows the compiler to bug you if you write new Foo.bar(); If precedence is modified in the way you propose, then you effectively get a call to static function through an instance (which in itself is valid operation), though that instance is immediately thrown away.

Forgot to mention the 'bad' side: Despite you actually do throw instance away as a result of such call, in case of non-static method it is done intentionally and with keeping in mind precisely what does Foo's ctor do, while in case of static call instance construction may be unexpected and lead to subtle difficult-to-trace bugs.

Oct 15 2010
parent bearophile <bearophileHUGS lycos.com> writes:
I was busy, I am back.
Indeed it wasn't a good idea.
Thank you for all the answers. 

Bye,
bearophile
Oct 17 2010
prev sibling next sibling parent Stanislav Blinov <blinov loniir.ru> writes:
  15.10.2010 19:43, Andrej Mitrovic wrote:
 Related: A nice alternative for quickly using anonymous objects is
 using the with statement, e.g.:

 with (new Foo)
 {
      foo();
      // ... more code
 }

 And after the with block the object doesn't exist anymore.
 Or you could bind it to some internal reference and keep it there,

I must ask, how can this binding be achieved?
 which wouldn't destroy it after exiting the with block. Many of the DFL GUI
 library code samples work this way, and it's quite a nice syntax imo.

Oct 18 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Here's an example from DFL where I'm using an anonymous Scintilla
object which is a subclass of a text editing widget in DFL (just
another window subclass), but behind the scenes it actually loads the
Scintilla DLL and behaves like a normal DFL text editing widget:

http://pastebin.com/YAduPRtF

What really happens in DFL is that assiging the "parent" variable of a
window class object (lets call it client) to another window class
object (call it host) means that the host now holds a reference to the
client. So the client will not be destroyed unless any of it's destroy
methods are explicitly called, or if the host window is destroyed then
the client window is destroyed as well (this is how DFL works).

I think that's how it works. If I'm wrong someone can correct me, though. :)

On 10/18/10, Stanislav Blinov <blinov loniir.ru> wrote:
   15.10.2010 19:43, Andrej Mitrovic wrote:
 Related: A nice alternative for quickly using anonymous objects is
 using the with statement, e.g.:

 with (new Foo)
 {
      foo();
      // ... more code
 }

 And after the with block the object doesn't exist anymore.
 Or you could bind it to some internal reference and keep it there,

I must ask, how can this binding be achieved?
 which wouldn't destroy it after exiting the with block. Many of the DFL
 GUI
 library code samples work this way, and it's quite a nice syntax imo.


Oct 18 2010
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Oops, the code came out a little fuzzy, here's the fixed one:

http://pastebin.com/kiXPeQLB

On 10/18/10, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 Here's an example from DFL where I'm using an anonymous Scintilla
 object which is a subclass of a text editing widget in DFL (just
 another window subclass), but behind the scenes it actually loads the
 Scintilla DLL and behaves like a normal DFL text editing widget:

 http://pastebin.com/YAduPRtF

 What really happens in DFL is that assiging the "parent" variable of a
 window class object (lets call it client) to another window class
 object (call it host) means that the host now holds a reference to the
 client. So the client will not be destroyed unless any of it's destroy
 methods are explicitly called, or if the host window is destroyed then
 the client window is destroyed as well (this is how DFL works).

 I think that's how it works. If I'm wrong someone can correct me, though.
 :)

 On 10/18/10, Stanislav Blinov <blinov loniir.ru> wrote:
   15.10.2010 19:43, Andrej Mitrovic wrote:
 Related: A nice alternative for quickly using anonymous objects is
 using the with statement, e.g.:

 with (new Foo)
 {
      foo();
      // ... more code
 }

 And after the with block the object doesn't exist anymore.
 Or you could bind it to some internal reference and keep it there,

I must ask, how can this binding be achieved?
 which wouldn't destroy it after exiting the with block. Many of the DFL
 GUI
 library code samples work this way, and it's quite a nice syntax imo.



Oct 18 2010