www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - OT: Airplane A = new Airplane()

reply "Charlie Patterson" <charliep1 excite.com> writes:
I've always wondered about the requirement of the word new in Java.  It 
appears Java (I don't know much about it) pretends there are no 
references/pointers to help the poor coder who can't handle it (so I've read 
as the reason):

   Airplane A = new Airplane();
   // work with A

   // Make a new Airplane for the following function
   Fly( new Airplane( bar, 3 ) );

    Airplane B;
    // dont' work with B yet or a run-time error occurs

So, with such an emphasis on "no pointers" and coddling the pre-school 
coder, why the use of the word new?  It feels very pointer'ish to me. 
Forgetting it would cause a strange thing called a bad reference.  Scary! 
Why not

   Airplane A;
   // use default airplane

   Airplane A = Airplane( 3 );
   // use specially constructed airplane
   // could have also just been a regular function like A = Init( 3 );

   // Make a new Airplane for the following function
   Fly( Airplane( bar, 3 ) );

This "new" practice has been copied to javascript, php, and now D.  Why? 
And before you hit me up with an efficiency issue, well OK, but these 
languages aren't bastions of efficiency and so why leave a possible run-time 
error hanging?
Feb 10 2005
next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Because, imho, constructors do things and moreover sometimes don't 
exist.  Your example would only not compile if Airplane had no 
constructor that took zero arguments.  Consider this code:

Airplane A;
try
    A = airport.getAirplane(AIRPLANE_FLYING);
catch (AirplaneHasCrashedException)
    A = airport.getAirplane(AIRPLANE_GROUND);

Okay, a dumb example I'm sure, but I think it illustrates the point.  I 
would be REQUIRED to add a dummy constructor, and a PUBLIC dummy 
constructor no less, to the Airplane class for that code to work under 
your example.

New, especially to Java and PHP users, definitely doesn't mean anything 
to do with pointers.  I write PHP software, actually, so I could 
definitely find you competent PHP programmers (meaning, ones who can 
write fairly well, not the best in the world, mind you) who have no idea 
what a pointer is.  PHP does not really use pointers, it uses reference 
counting all behind the scenes.  Most PHP programmers don't totally even 
understand explicit references.

-[Unknown]


 I've always wondered about the requirement of the word new in Java.  It 
 appears Java (I don't know much about it) pretends there are no 
 references/pointers to help the poor coder who can't handle it (so I've read 
 as the reason):
 
    Airplane A = new Airplane();
    // work with A
 
    // Make a new Airplane for the following function
    Fly( new Airplane( bar, 3 ) );
 
     Airplane B;
     // dont' work with B yet or a run-time error occurs
 
 So, with such an emphasis on "no pointers" and coddling the pre-school 
 coder, why the use of the word new?  It feels very pointer'ish to me. 
 Forgetting it would cause a strange thing called a bad reference.  Scary! 
 Why not
 
    Airplane A;
    // use default airplane
 
    Airplane A = Airplane( 3 );
    // use specially constructed airplane
    // could have also just been a regular function like A = Init( 3 );
 
    // Make a new Airplane for the following function
    Fly( Airplane( bar, 3 ) );
 
 This "new" practice has been copied to javascript, php, and now D.  Why? 
 And before you hit me up with an efficiency issue, well OK, but these 
 languages aren't bastions of efficiency and so why leave a possible run-time 
 error hanging?
 
 

Feb 10 2005
next sibling parent reply "Charlie Patterson" <charliep1 excite.com> writes:
 Airplane A;
 try
    A = airport.getAirplane(AIRPLANE_FLYING);
 catch (AirplaneHasCrashedException)
    A = airport.getAirplane(AIRPLANE_GROUND);

 Okay, a dumb example I'm sure, but I think it illustrates the point.  I 
 would be REQUIRED to add a dummy constructor, and a PUBLIC dummy 
 constructor no less, to the Airplane class for that code to work under 
 your example.

Good one! But I can claim that if you don't have a default constructor, then "Airplane A;" is a compile time error. This would avoid the 'new' keyword.
Feb 10 2005
parent reply xs0 <xs0 xs0.com> writes:
Well, for one thing, Airplane() could be a function or method; if 
there's a new in front of it, you immediately know that it's a class. 
(and code obviousness is rather important, if you ask me; quite a lot of 
projects are worked on by more than one person...).

Plus, in many cases you don't want an object immediately, but at some 
point in the future (think lazy initialization). How would you handle that?


xs0

PS: What's wrong with D's efficiency?


Charlie Patterson wrote:
Airplane A;
try
   A = airport.getAirplane(AIRPLANE_FLYING);
catch (AirplaneHasCrashedException)
   A = airport.getAirplane(AIRPLANE_GROUND);

Okay, a dumb example I'm sure, but I think it illustrates the point.  I 
would be REQUIRED to add a dummy constructor, and a PUBLIC dummy 
constructor no less, to the Airplane class for that code to work under 
your example.

Good one! But I can claim that if you don't have a default constructor, then "Airplane A;" is a compile time error. This would avoid the 'new' keyword.

Feb 10 2005
next sibling parent reply "Charlie Patterson" <charliep1 excite.com> writes:
"xs0" <xs0 xs0.com> wrote in message news:cuggsr$2u8a$1 digitaldaemon.com...
 Well, for one thing, Airplane() could be a function or method; if there's 
 a new in front of it, you immediately know that it's a class. (and code 
 obviousness is rather important, if you ask me; quite a lot of projects 
 are worked on by more than one person...).

 Plus, in many cases you don't want an object immediately, but at some 
 point in the future (think lazy initialization). How would you handle 
 that?

Yeah, I guess you'd have to have a rule that you can't name a function the same as an object name. Then again, if I wanted to initialize a class with some non-member function, why couldn't I? Or you could take the tact that I believe D does and have Airplane A = this( 3 ); Airplane B; b = this(); Now "this()" is a reserved function and you know what is going on when you see it. As for your second point, about lazy initialization: I don't see why garbage collected languages care that much. It seems ease of understanding and coding take the front seat and efficiency loss can be tolerated. A smarter compiler could wait to use a default constructor when the object it first used, perhaps? Airplane A; // no constructor; saves time A.rotor = ROTOR_PROP; // first use, sneak in a default constructor. Just ideas.
Feb 10 2005
next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Again, this is just my opinion, but you're ignoring that constructors do 
things again!  Consider this:

// Default constructor for Backup loads all the data from /var/airport 
into memory.
Backup back;

foreach (char[] file; listfiles("/var/airport"))
    remove(file);

back.SaveBackup();

Another dumb example, but it illustrates my point again, I think.  And I 
know you'll come back and say, well, you'd just do this:

Backup back = Backup();

To force the constructor to be run, but... still.... it's confusing.

Anyway, getting rid of new would also make D less comfortable for C/C++ 
users, which is one thing it's seemed to push...

As for this(), it's less searchable imho.  A lot of programmers use 
tools like lxr, and being able to search for constructor usage is a Good 
Thing.

-[Unknown]


 As for your second point, about lazy initialization: I don't see why garbage 
 collected languages care that much.  It seems ease of understanding and 
 coding take the front seat and efficiency loss can be tolerated.  A smarter 
 compiler could wait to use a default constructor when the object it first 
 used, perhaps?
 
     Airplane A; // no constructor; saves time
 
     A.rotor = ROTOR_PROP; // first use, sneak in a default constructor.
 
 Just ideas.

Feb 10 2005
prev sibling parent reply xs0 <xs0 xs0.com> writes:
 Yeah, I guess you'd have to have a rule that you can't name a function the 
 same as an object name.

Still, AFAIK, that would break the context-freeness of D's grammar, which Walter stated as one of the design goals of the language.
 Then again, if I wanted to initialize a class with some non-member function, 
 why couldn't I?  Or you could take the tact that I believe D does and
 have
 
     Airplane A = this( 3 );
     Airplane B;
 
    b = this();

That's even worse. this primarily refers to the object instance in a method (i.e. void setX(double x) { this.x=x; }), not to the constructor..
 Now "this()" is a reserved function and you know what is going on when you 
 see it.

Sure, you do now. With your semantics you wouldn't..
 As for your second point, about lazy initialization: I don't see why garbage 
 collected languages care that much.  It seems ease of understanding and 
 coding take the front seat and efficiency loss can be tolerated.  

What does lazy initialization have to do with languages? It's just a common programming technique. Anyhow, consider for example a cache or pool of something; how would you initialize it non-lazily?
 A smarter compiler could wait to use a default constructor when the object 
 it first used, perhaps?
 
     Airplane A; // no constructor; saves time
 
     A.rotor = ROTOR_PROP; // first use, sneak in a default constructor.

What if it's constructed somewhere else? And usually, if a null is accessed, it's an error that should not be ignored by constructing the object (btw, this would also mean that practically every object access would need the null check).. xs0
Feb 11 2005
parent reply "Charlie Patterson" <charliep1 excite.com> writes:
"xs0" <xs0 xs0.com> wrote in message news:cui9fv$1sr0$1 digitaldaemon.com...
 Yeah, I guess you'd have to have a rule that you can't name a function 
 the same as an object name.

Still, AFAIK, that would break the context-freeness of D's grammar, which Walter stated as one of the design goals of the language.

I don't know about this assumption, but still I don't see how this breaks context-free. If a function returns an Airplane, it is a syntax error to assign it to anything but an Airplane (or base class). Nothing new.
 Then again, if I wanted to initialize a class with some non-member 
 function, why couldn't I?  Or you could take the tact that I believe D 
 does and
 have

     Airplane A = this( 3 );
     Airplane B;

    b = this();

That's even worse. this primarily refers to the object instance in a method (i.e. void setX(double x) { this.x=x; }), not to the constructor..

I'm new to reading about D, but I don't think I started it. Doesn't D use this() and ~this() for construction and destruction? Sure it doesn't require the coder using these words to actually create an instance, but they are used as function names nonetheless.
 As for your second point, about lazy initialization: I don't see why 
 garbage collected languages care that much.  It seems ease of 
 understanding and coding take the front seat and efficiency loss can be 
 tolerated.


 What does lazy initialization have to do with languages? It's just a 
 common programming technique. Anyhow, consider for example a cache or pool 
 of something; how would you initialize it non-lazily?

Some languages are inefficient for some problem domains because they allocate memory early and often. The member initialization feature for C++ is designed to remove any unnecessary construction: class Airplane { string pilot; ... }; Airplane::Airplane ( ) { pilot = "none"; } By the time pilot is set to "none" in the constructor, a default string was already created, and now it is being reassigned, all with the heap (= expensive) memory. Instead do: Airplane::Airplane ( ) : pilot( "non" ) { } Not beautiful, but it is super efficient and avoids any non-lazy initialization. Conversely, a language that is going for simplicity (over a little performance) could avoid the C++ trick AND the run-time null object problem by initializing every object, even "Airplane A;" with some default. After all, ints, bits and every other built-in type have to have *some* value. Why shouldn't *all* objects have some value instead of putting them in between. This confuses me about the ideology of these languages. Why try to remove pointers because they are buggy, but then leave a freakin' pointer for objects? Make an object feel substantial, just like an int. I guess the creators of these languages feel it is too big of an efficiency hit, because, again I don't see why they should rail against pointers and then leave the biggest of all dangling like that. As for initializing a cache or pool or something, make an empty pool instead of a null pointer to a non-pool. The user can immediately re-instantiate it with a better one, at a small cost in time.
 A smarter compiler could wait to use a default constructor when the 
 object it first used, perhaps?

     Airplane A; // no constructor; saves time

     A.rotor = ROTOR_PROP; // first use, sneak in a default constructor.

What if it's constructed somewhere else? And usually, if a null is accessed, it's an error that should not be ignored by constructing the object (btw, this would also mean that practically every object access would need the null check)..

Alternatively objects could become slightly heavier and, instead of being a simple pointer to memory, they could be a pointer and an init flag... Again, more costly but it bring the ideology of objects as first class entities to fruition. Currently I can create ints and use them, but I can't just create an Airplane and start using it == not first class. int i; i = 0; // of course, you have made an int; Airplane A; A.rotor = ROTOR_PROPR; // oops! you didn't really make an airplane
Feb 11 2005
parent reply xs0 <xs0 xs0.com> writes:
 I don't know about this assumption, but still I don't see how this breaks 
 context-free.  If a function returns an Airplane, it is a syntax error to 
 assign it to anything but an Airplane (or base class).  Nothing new.

perform(task(...)) is task a class or a function?
 I'm new to reading about D, but I don't think I started it.  Doesn't D use 
 this() and ~this() for construction and destruction?  Sure it doesn't 
 require the coder using these words to actually create an instance, but they 
 are used as function names nonetheless.

Sure, but "this" has a different meaning except in the specific context of being used as a method name within a class..
 Not beautiful, but it is super efficient and avoids any non-lazy 
 initialization.  Conversely, a language that is going for simplicity (over a 
 little performance) could avoid the C++ trick AND the run-time null object 
 problem by initializing every object, even "Airplane A;" with some default. 

But you need null at least sometimes (see other posts). If you do have nulls, you can't completely avoid the run-time null object problem. And like I already stated in another post, having null and crashing can be much better than having a default object instead of the null and not crashing.
 After all, ints, bits and every other built-in type have to have *some* 
 value.  Why shouldn't *all* objects have some value instead of putting them 
 in between.  This confuses me about the ideology of these languages.  Why 
 try to remove pointers because they are buggy, but then leave a freakin' 
 pointer for objects?  Make an object feel substantial, just like an int.

Well, it does somewhat suck that primitive types are treated differently than structs and again differently than classes. But each serves their own purpose, so why would you take that away? A good-for-everything is great-for-nothing.
 I guess the creators of these languages feel it is too big of an efficiency 
 hit, because, again I don't see why they should rail against pointers and 
 then leave the biggest of all dangling like that.

Pointers aren't all bad, it's just what you can do in C with them that's bad :) And it's not pointers that are buggy, it's programmers :)
 As for initializing a cache or pool or something, make an empty pool instead 
 of a null pointer to a non-pool.  The user can immediately re-instantiate it 
 with a better one, at a small cost in time.

Ahh, but how do I make the empty pool (or a half-filled pool for that matter)? Should I reallocate arrays and copy contents of the pool's vars on each and every addition/removal? Isn't that more error-prone than handling nulls?
 Alternatively objects could become slightly heavier and, instead of being a 
 simple pointer to memory, they could be a pointer and an init flag... 
 Again, more costly but it bring the ideology of objects as first class 
 entities to fruition.  Currently I can create ints and use them, but I can't 
 just create an Airplane and start using it == not first class.
 
     int i;
     i = 0;  // of course, you have made an int;
     Airplane A;
     A.rotor = ROTOR_PROPR; // oops!  you didn't really make an airplane

Sure you can: Airplane A; A=null; A=someOtherAirplane; You just didn't make A.rotor :) But seriously, it's exactly like saying doubles should never have the NaN value, even though NaNs are extremely useful in some contexts, although they behave almost like nulls (i.e. they fail your arithmetics and/or comparisons; heck, they're even not equal to themselves). And AFAIK, dividing an integer by zero will cause exceptions on most systems, would you eliminate that as well? What should happen in that case? Isn't that a source of crashes? Would you then forbid the value 0 of ever being stored in memory? xs0
Feb 11 2005
parent "Charlie Patterson" <charliep1 excite.com> writes:
Lots of good points in here!

"xs0" <xs0 xs0.com> wrote in message news:cuishj$2i1t$1 digitaldaemon.com...
 I don't know about this assumption, but still I don't see how this breaks 
 context-free.  If a function returns an Airplane, it is a syntax error to 
 assign it to anything but an Airplane (or base class).  Nothing new.

perform(task(...)) is task a class or a function?

Why does it matter? Apparently it is a "function" which might be a member constructor function.
 After all, ints, bits and every other built-in type have to have *some* 
 value.  Why shouldn't *all* objects have some value instead of putting 
 them in between.  This confuses me about the ideology of these languages. 
 Why try to remove pointers because they are buggy, but then leave a 
 freakin' pointer for objects?  Make an object feel substantial, just like 
 an int.

Well, it does somewhat suck that primitive types are treated differently than structs and again differently than classes. But each serves their own purpose, so why would you take that away? A good-for-everything is great-for-nothing.

I thought primitives and structs works the same, allocation-wize. So only classes feel different in that respect. Its fine to have an exception if it buys a lot, but I don't see it here.
 As for initializing a cache or pool or something, make an empty pool 
 instead of a null pointer to a non-pool.  The user can immediately 
 re-instantiate it with a better one, at a small cost in time.

Ahh, but how do I make the empty pool (or a half-filled pool for that matter)? Should I reallocate arrays and copy contents of the pool's vars on each and every addition/removal? Isn't that more error-prone than handling nulls?

Maybe I'm being confusing. In C/C++, a pool would probably have a size and a pointer to an array of values. A default constructor would probably set the size to 0 and the pointer to null. In D, I guess an array would be created with no values in it. The first thing a user might do is either use a different constructor or, if it is his style, call a resize function: Pool P1( 100 ); Pool P2; P2.resize( 100 ); This is less efficient, but pretty natural. It creates an unnecessary array and then replaces it. This costs something but it looks natural. I don't thinking remembering to create a "new Pool()" is natural for people who don't think in allocation terms. And, again, it doesn't cost much for those of us who do think in memory terms (although some objects may have a hard time having a small default footprint, that's probably rare and the program is probably huge at run-time anyway.)
 Alternatively objects could become slightly heavier and, instead of being 
 a simple pointer to memory, they could be a pointer and an init flag... 
 Again, more costly but it bring the ideology of objects as first class 
 entities to fruition.  Currently I can create ints and use them, but I 
 can't just create an Airplane and start using it == not first class.

     int i;
     i = 0;  // of course, you have made an int;
     Airplane A;
     A.rotor = ROTOR_PROPR; // oops!  you didn't really make an airplane

Sure you can: Airplane A; A=null; A=someOtherAirplane; But you need null at least sometimes (see other posts). If you do have nulls, you can't completely avoid the run-time null object problem. And like I already stated in another post, having null and crashing can be much better than having a default object instead of the null and not crashing.

 You just didn't make A.rotor :) But seriously, it's exactly like saying 
 doubles should never have the NaN value, even though NaNs are extremely 
 useful in some contexts, although they behave almost like nulls (i.e. they 
 fail your arithmetics and/or comparisons; heck, they're even not equal to 
 themselves).

There's the crux. Nan is very useful, but does that mean objects should have the equivalent? Ints don't have one. Bits don't have one. (There is such a thing as tri-variate boolean yes, no, and undefined). A coder has to create a bool to keep up with an int or bool to say it is undefined. Why should objects get to cheat here and have a special value for it? And at the cost of the complexity of needing to do a "new"? And technically, a floating NaN shouldn't be used to mean undefined, but that's a big debate. Put differently, if you are worried about coders who have trouble with the idea of deleting memory at the end of pointers, you probably don't want the idea of a non-object (null).
 And AFAIK, dividing an integer by zero will cause exceptions on most 
 systems, would you eliminate that as well? What should happen in that 
 case? Isn't that a source of crashes? Would you then forbid the value 0 of 
 ever being stored in memory?

Again, in my mind there is a difference between an error state and a "does not exist" state. Even so, if you have ideas to make 0's safer, I'd be all ears. (-: So back to my point, I'm not (necessarily) trying to change D. I have simply wondered for ten years why Java did it and it was copied into ecmascript and php at least.
Feb 11 2005
prev sibling next sibling parent "Charlie Patterson" <charliep1 excite.com> writes:
"xs0" <xs0 xs0.com> wrote in message news:cuggsr$2u8a$1 digitaldaemon.com...
 PS: What's wrong with D's efficiency?

I'm not proficient in D in the slightest so I'm not sure how much D does or doesn't care about extreme efficiency. Although I have seen the benchmarks that beat C on some things, so I guess it is considered important. I was just talking off topic.
Feb 10 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
I think this idea has merit. However.. it's getting later in the game and  
something this fundamental will break existing code.

On Thu, 10 Feb 2005 21:41:08 +0100, xs0 <xs0 xs0.com> wrote:
 Well, for one thing, Airplane() could be a function or method; if  
 there's a new in front of it, you immediately know that it's a class.  
 (and code obviousness is rather important, if you ask me; quite a lot of  
 projects are worked on by more than one person...).

Why does it matter whether it's a constructor or a free function, both are returning an Airplane. If both the function name and object returned are the same then it's a constructor, otherwise it's not. This assumes functions cannot be named the same as an object, which I believe is the case already.
 Plus, in many cases you don't want an object immediately, but at some  
 point in the future (think lazy initialization). How would you handle  
 that?

Airplane A = null; If you assume that it's more likely you want to construct something than not, then this is no chore. It also means that if the programmer intends not to construct something they actually have to say so. So, as the OP mentions you can't forget to construct it, you can only forget not to, meaning you trade a possible runtime crash (or compile time error) for a potentially negligible performance hit.
 PS: What's wrong with D's efficiency?

It's pretty good and is likely to improve. Unless, we trade some of it off for more advanced features, hopefully there is a way to have both. Regan
 Charlie Patterson wrote:
 Airplane A;
 try
   A = airport.getAirplane(AIRPLANE_FLYING);
 catch (AirplaneHasCrashedException)
   A = airport.getAirplane(AIRPLANE_GROUND);

 Okay, a dumb example I'm sure, but I think it illustrates the point.   
 I would be REQUIRED to add a dummy constructor, and a PUBLIC dummy  
 constructor no less, to the Airplane class for that code to work under  
 your example.

constructor, then "Airplane A;" is a compile time error. This would avoid the 'new' keyword.


Feb 10 2005
parent reply xs0 <xs0 xs0.com> writes:
 Why does it matter whether it's a constructor or a free function, both 
 are  returning an Airplane.

Because it's really different if you get a new instance or an old instance. If you see new, you know it's a new instance, if you don't see it, you don't know what you'll get unless you go look it up..
 It also means that if the programmer intends not to construct something  
 they actually have to say so. 

You would trade implicitly doing nothing to implicitly constructing an object. Which is more obvious?
 So, as the OP mentions you can't forget to  construct it, you can only 
 forget not to, meaning you trade a possible  runtime crash (or
 compile time error) for a potentially negligible  performance hit.

Just because something is null, it doesn't mean that a default object will be better, it can easily be much worse.. Usually, when an error occurs (such as a null reference when it shouldn't be), it's best to stop, not to continue in some undefined way.. Consider this: class Selection { this() { // initialize to everything } void filter(..) { // select some things } } class DeleteOp { Selection selection; void setSelection(Selection newSelection) { this.selection=newSelection; } void doDelete() { // delete all things in selection } } Now, if you forget to setSelection(), wouldn't you prefer a runtime error than to have everything deleted? xs0
Feb 11 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 11 Feb 2005 13:59:05 +0100, xs0 <xs0 xs0.com> wrote:
 Why does it matter whether it's a constructor or a free function, both  
 are  returning an Airplane.

Because it's really different if you get a new instance or an old instance. If you see new, you know it's a new instance, if you don't see it, you don't know what you'll get unless you go look it up..

Why do you need to know whether it's 'new' or not? How are you going to treat it differently?
 It also means that if the programmer intends not to construct  
 something  they actually have to say so.

You would trade implicitly doing nothing to implicitly constructing an object. Which is more obvious?

"implicitly doing nothing" I agree. However, I think that is beside the point. As I see it people most commonly want to construct something. Failure to do so causes a seg fault. If it was changed then: - the most common case would be handled automatically. - the seg fault can not occur. Further, the option for 'optimising' by not constructing is still available, so we've lost nothing.
 So, as the OP mentions you can't forget to  construct it, you can only

> compile time error) for a potentially negligible performance hit. Just because something is null, it doesn't mean that a default object will be better, it can easily be much worse..

It's not a matter of 'better' or 'worse' it's a matter of what the most common intent was. I'm arguing that most commonly they mean't to construct it. esp people coming from C++ eg. class A{} void foo() { A a; } in C++ the above would have constructed 'a'.
 Usually, when an error occurs (such as a null reference when it  
 shouldn't be), it's best to stop, not to continue in some undefined way..

I agree totally. Consider these 2 cases: class A {} 1) void main() { A a; a.member = 5; //crash, programmer forgot to 'new A()' } 2) void main() { A a; a = new A(); } In #1 the programmer made a mistake, the result is a seg fault. If the new behaviour was adopted then there would be no crash, and the program would behave 'exactly' as the programmer intended. In #2 the programmer intended to construct later. If the new behaviour was adopted then all that would change is that the class would be constructed twice (which can possibly be optimised away by the compiler in simple cases, or by '= null' by the programmer), and the program will behave 'exactly' as the programmer intended.
 Consider this:

 class Selection
 {
      this()
      {
          // initialize to everything
      }

      void filter(..)
      {
          // select some things
      }
 }

 class DeleteOp
 {
      Selection selection;

      void setSelection(Selection newSelection)
      {
          this.selection=newSelection;
      }

      void doDelete()
      {
          // delete all things in selection
      }
 }


 Now, if you forget to setSelection(), wouldn't you prefer a runtime  
 error than to have everything deleted?

Sure, however.. I have never encountered, nor had cause to write a container class that added 'everything' upon construction. I would argue that your example is an example of weird/bad design and thus a rare case. Regan
Feb 13 2005
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
For at least the fourth time, constructors *DO* things.  It is very 
likely calling a contructor twice would be a BAD thing.

Consider a logging class.  Perhaps the first call checks a file, and 
clears the log of all entries older than the time specified in the file, 
and then updates it to now.  The purpose would be to only show the last 
construction onward's worth of log entries.  Calling it twice is 
obviously an error.

Consider a constructor that perhaps opens a socket to another host, and 
waits for a response.  In cases, you could double or more the latency by 
trying it twice!

Calling a constructor twice may work in simple examples, but not in the 
real world.  And yes, the programmer could maybe specifically set it to 
null, but that's not what *you're* asserting.

If this *is* changed, it would have to be before 1.0.  Either way, your 
assertions that depend on the constructor being called twice not really 
mattering hold no water at all.

-[Unknown]


 In #2 the programmer intended to construct later. If the new behaviour 
 was  adopted then all that would change is that the class would be 
 constructed  twice (which can possibly be optimised away by the compiler 
 in simple  cases, or by '= null' by the programmer), and the program 
 will behave  'exactly' as the programmer intended.

Feb 13 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 13 Feb 2005 15:25:07 -0800, Unknown W. Brackets  
<unknown simplemachines.org> wrote:
 For at least the fourth time, constructors *DO* things.  It is very  
 likely calling a contructor twice would be a BAD thing.

Sure, sometimes there will be ill effects to calling it twice.
 Consider a logging class.  Perhaps the first call checks a file, and  
 clears the log of all entries older than the time specified in the file,  
 and then updates it to now.  The purpose would be to only show the last  
 construction onward's worth of log entries.  Calling it twice is  
 obviously an error.

Perhaps. In this case if they were close together it would have no ill effect.
 Consider a constructor that perhaps opens a socket to another host, and  
 waits for a response.  In cases, you could double or more the latency by  
 trying it twice!

Sure, which is why it would be a bug to omit the '= null' in this and the other cases you have presented. However, I argue that it's more common to want to construct immediately. I'd also argue that when using classes with side effects as you describe you'd program more carefully and would be less likely to forget the '= null'. Less likely than when using a common class with no side effects.
 Calling a constructor twice may work in simple examples, but not in the  
 real world.

In the real world, the basic classes tend to be strings and containers, all of which can be constructed twice to no ill effect (except wasted time). It's only the more advanced classes, which you should be more careful with in general, that have a real problem with dual construction.
 And yes, the programmer could maybe specifically set it to null, but  
 that's not what *you're* asserting.

? The comment to which you're replying mentions it. So I'm not sure what you're saying.
 In #2 the programmer intended to construct later. If the new behaviour  
 was  adopted then all that would change is that the class would be  
 constructed  twice (which can possibly be optimised away by the  
 compiler in simple  cases, or by '= null' by the programmer), and the  
 program will behave  'exactly' as the programmer intended.


 If this *is* changed, it would have to be before 1.0.

Like I said in my initial reply, we're probably too late in the game for a change like this.
 Either way, your assertions that depend on the constructor being called  
 twice not really mattering hold no water at all.

In your opinion. Regan
Feb 13 2005
prev sibling parent reply Matthias Becker <Matthias_member pathlink.com> writes:
Well, for one thing, Airplane() could be a function or method; if 
there's a new in front of it, you immediately know that it's a class. 
(and code obviousness is rather important, if you ask me; quite a lot of 
projects are worked on by more than one person...).

Oh, those poor C++-Programmers. In C++ you create objects without new, if you want them to be on the stack. In ML-like languages you call constructors without new, too. And nobody is confused.
Plus, in many cases you don't want an object immediately, but at some 
point in the future (think lazy initialization). How would you handle that?

Right, I don't like th original proposal, too. I'd vote for # Airplain foo; stays as is. But we still don't need 'new': Airplain foo = Airplain(); -- Matthias Becker
Feb 11 2005
next sibling parent reply Nick <Nick_member pathlink.com> writes:
In article <cuinrp$2cva$1 digitaldaemon.com>, Matthias Becker says...
Right, I don't like th original proposal, too.
I'd vote for
#   Airplain foo;
stays as is.

But we still don't need 'new':
Airplain foo = Airplain();

This breaks opCall. (And you can get the effect you want already by writing your own opCall.) How about just: Airplane foo(10); equivalent to Airplane foo = new Airplane(10); Airplane foo(); equivalent to Airplane foo = new Airplane; Airplane foo; same as now This eliminates many cases of 'new' without breaking a single line of existing code. I'm surprised nobody have suggested this yet. (Or if they have I have just missed it :-) Nick
Feb 11 2005
next sibling parent Kris <Kris_member pathlink.com> writes:
I have to say that I rather like opCall. You can do some subtle yet powerful
things with it. Not quite up there with slices and contracts, but very cool in
it's own little way.

- Kris


In article <cuiqfm$2g4k$1 digitaldaemon.com>, Nick says...
In article <cuinrp$2cva$1 digitaldaemon.com>, Matthias Becker says...
Right, I don't like th original proposal, too.
I'd vote for
#   Airplain foo;
stays as is.

But we still don't need 'new':
Airplain foo = Airplain();

This breaks opCall. (And you can get the effect you want already by writing your own opCall.) How about just: Airplane foo(10); equivalent to Airplane foo = new Airplane(10); Airplane foo(); equivalent to Airplane foo = new Airplane; Airplane foo; same as now This eliminates many cases of 'new' without breaking a single line of existing code. I'm surprised nobody have suggested this yet. (Or if they have I have just missed it :-) Nick

Feb 11 2005
prev sibling next sibling parent reply "Charlie Patterson" <charliep1 excite.com> writes:
"Nick" <Nick_member pathlink.com> wrote in message 
news:cuiqfm$2g4k$1 digitaldaemon.com...
 How about just:

 Airplane foo(10);   equivalent to    Airplane foo = new Airplane(10);
 Airplane foo();     equivalent to    Airplane foo = new Airplane;
 Airplane foo;       same as now

You would also need a way to create a new instance without the word 'new' in-line: Fly( Airplane(10) ); Fly( Airplane() );
Feb 11 2005
parent reply Nick <Nick_member pathlink.com> writes:
In article <cuj0dt$2lup$1 digitaldaemon.com>, Charlie Patterson says...
 Airplane foo(10);   equivalent to    Airplane foo = new Airplane(10);
 Airplane foo();     equivalent to    Airplane foo = new Airplane;
 Airplane foo;       same as now

You would also need a way to create a new instance without the word 'new' in-line: Fly( Airplane(10) ); Fly( Airplane() );

Why? Nick
Feb 11 2005
parent "Charlie Patterson" <charliep1 excite.com> writes:
"Nick" <Nick_member pathlink.com> wrote in message 
news:cuj4hg$2q2b$1 digitaldaemon.com...
 In article <cuj0dt$2lup$1 digitaldaemon.com>, Charlie Patterson says...
 Airplane foo(10);   equivalent to    Airplane foo = new Airplane(10);
 Airplane foo();     equivalent to    Airplane foo = new Airplane;
 Airplane foo;       same as now

You would also need a way to create a new instance without the word 'new' in-line: Fly( Airplane(10) ); Fly( Airplane() );

Why?

Because you don't always create a new instance just when you declare a variable. Sometimes you need a new instance "in-line."
Feb 11 2005
prev sibling parent reply Matthias Becker <Matthias_member pathlink.com> writes:
Right, I don't like th original proposal, too.
I'd vote for
#   Airplain foo;
stays as is.

But we still don't need 'new':
Airplain foo = Airplain();

This breaks opCall. (And you can get the effect you want already by writing your own opCall.)

Damn, your right :(
How about just:

Airplane foo(10);   equivalent to    Airplane foo = new Airplane(10);
Airplane foo();     equivalent to    Airplane foo = new Airplane;
Airplane foo;       same as now

This eliminates many cases of 'new' without breaking a single line of existing
code. I'm surprised nobody have suggested this yet. (Or if they have I have just
missed it :-)

I like it :) -- Matthias Becker
Feb 14 2005
parent Georg Wrede <georg.wrede nospam.org> writes:
How about just:

Airplane foo(10);   equivalent to    Airplane foo = new Airplane(10);
Airplane foo();     equivalent to    Airplane foo = new Airplane;
Airplane foo;       same as now

This eliminates many cases of 'new' without breaking a single line of existing
code. I'm surprised nobody have suggested this yet. (Or if they have I have just
missed it :-)

I like it :) -- Matthias Becker

This looks excellent!!
Feb 14 2005
prev sibling parent xs0 <xs0 xs0.com> writes:
 Oh, those poor C++-Programmers.
 In C++ you create objects without new, if you want them to be on the stack. In
 ML-like languages you call constructors without new, too. And nobody is
 confused.

I'm not a C++ programmer :P And who says nobody is confused? What is a stack anyway? (I know it, but many people don't; I also know that the right amount of verbosity is certainly better than too little or too much; new as-is to me feels just right)
 But we still don't need 'new':
 Airplain foo = Airplain();

well, that seems OK, but how about Airplane foo = Fighter(); // function/class? or even Task(...).process(); is that a new task, or something looked up? if you have new, there's no ambiguity there.. xs0
Feb 11 2005
prev sibling parent Matthias Becker <Matthias_member pathlink.com> writes:
Because, imho, constructors do things and moreover sometimes don't 
exist.  Your example would only not compile if Airplane had no 
constructor that took zero arguments.  Consider this code:

Airplane A;
try
    A = airport.getAirplane(AIRPLANE_FLYING);
catch (AirplaneHasCrashedException)
    A = airport.getAirplane(AIRPLANE_GROUND);

Okay, a dumb example I'm sure, but I think it illustrates the point.  I 
would be REQUIRED to add a dummy constructor, and a PUBLIC dummy 
constructor no less, to the Airplane class for that code to work under 
your example.

Nope. # Airplane A = null; # try # A = airport.getAirplane(AIRPLANE_FLYING); # catch (AirplaneHasCrashedException) # A = airport.getAirplane(AIRPLANE_GROUND); -- Matthias Becker
Feb 11 2005
prev sibling next sibling parent "Craig Black" <cblack ara.com> writes:
I like the idea.

-Craig 
Feb 10 2005
prev sibling next sibling parent reply David Medlock <amedlock nospam.org> writes:
Charlie Patterson wrote:
 I've always wondered about the requirement of the word new in Java.  It 
 appears Java (I don't know much about it) pretends there are no 
 references/pointers to help the poor coder who can't handle it (so I've read 
 as the reason):

Actually in Java ALL objects are referenced by a 'pointer' (called a reference, which is in effect a safe pointer). Personally I think true pointers are a wonderful source of bugs and should be consigned to OS and device driver development.
 
    Airplane A = new Airplane();
    // work with A
 
    // Make a new Airplane for the following function
    Fly( new Airplane( bar, 3 ) );
 
     Airplane B;
     // dont' work with B yet or a run-time error occurs

I would argue that allocation of memory should be in big neon letters, since that is usually the slower parts of most imperative languages. Simplicity is a goal of D. C++ has gone overboard here:(from http://nothings.org/computer/cpp.html) [quote] In C++ there are eight syntaces and quite a few semantics. No joke: 1. regular function call (expression context): foo(a,b) 2. constructor call (declaration context): Foo foo 3. constructor call (declaration context): Foo foo(a,b) 4. constructor call (expression context): new Foo 5. constructor call (expression context): new Foo(a,b) 6. destructor call (block end): } 7. destructor call (statement context): delete foo; 8. overloaded operator (expression context): foo+bar (I'll fold copy/assignment constructors in with overloaded operators.) [/quote] I would say cleaning up those issues is a _good_ thing. If you want stack allocation use structs, heap allocation use classes. Its very straightforward. It doesnt save THAT much typing and the readability is much better.
Feb 11 2005
parent reply "Charlie Patterson" <charliep1 excite.com> writes:
 Actually in Java ALL objects are referenced by a 'pointer' (called a 
 reference, which is in effect a safe pointer).  Personally I think true 
 pointers are a wonderful source of bugs and should be consigned to OS and 
 device driver development.

While we're on that subject, why let OS guys do it either?
 I would argue that allocation of memory should be in big neon letters, 
 since that is usually the slower parts of most imperative languages. 
 Simplicity is a goal of D.

I would think the "simpler" thing would be to have less keywords and syntax. But again, I'm mostly asking out of curiosity, not to change D. I just wonder about the original of some quirks I've never understood.
 C++ has gone overboard here:(from http://nothings.org/computer/cpp.html)

 [quote]
 In C++ there are eight syntaces and quite a few semantics.

 No joke:

    1. regular function call (expression context): foo(a,b)
    2. constructor call (declaration context): Foo foo
    3. constructor call (declaration context): Foo foo(a,b)
    4. constructor call (expression context): new Foo
    5. constructor call (expression context): new Foo(a,b)
    6. destructor call (block end): }
    7. destructor call (statement context): delete foo;
    8. overloaded operator (expression context): foo+bar

 (I'll fold copy/assignment constructors in with overloaded operators.)
 [/quote]

I think C++ is complicated but I think that list isn't really fair. It basically has two orthogonal issues: building on the stack vs heap (new or not new) and listing parameters, which can be done without the () if there are none. Two basic rules, not 8 "syntaxes." Further, if D has just one syntax, then why add the word "new". Any constuctor will use the heap and doesn't need the memory deleted manually. So why use a keyword that drums up visions of stack vs heap debates and manual memory allocation?
Feb 11 2005
parent David Medlock <amedlock nospam.org> writes:
Charlie Patterson wrote:
Actually in Java ALL objects are referenced by a 'pointer' (called a 
reference, which is in effect a safe pointer).  Personally I think true 
pointers are a wonderful source of bugs and should be consigned to OS and 
device driver development.

While we're on that subject, why let OS guys do it either?

Because they are writing drivers for a specific piece of hardware. OS writers(the ones I mean) are dealing with those drivers which expect specific values in a fixed format ( many times in memory not allocated by them).
I would argue that allocation of memory should be in big neon letters, 
since that is usually the slower parts of most imperative languages. 
Simplicity is a goal of D.

I would think the "simpler" thing would be to have less keywords and syntax. But again, I'm mostly asking out of curiosity, not to change D. I just wonder about the original of some quirks I've never understood.

I see why your examples are *different*, I dont see why they are *better* semantics than D has. At least I hope we are discussing semantics. Syntax is mostly a matter of taste...
C++ has gone overboard here:(from http://nothings.org/computer/cpp.html)


 
 
 I think C++ is complicated but I think that list isn't really fair.  It 
 basically has two orthogonal issues: building on the stack vs heap (new or 
 not new) and listing parameters, which can be done without the () if there 
 are none.  Two basic rules, not 8 "syntaxes."
 

Actually you have to remember a lot more than that. Especially in reguards to calls made outside the scope where the constructor occurs. There are pointers to objects, objects themselves, and references to objects. Mix in the 'silent' C++ overloaded casting and you have an even bigger mess. Calling a function with a reference to a local object, which goes out of scope is a PITA. If you have a copy constructor then all is probably well, otherwise it probably isn't. These types of memory corruption errors don't always fail. It depends entirely on the stack after the call which is not always fixed. In D there are only 2 semantics to ever think about. Value semantics(structs) and reference semantics(classes). I don't see how your examples (or C++) are simpler than this.
 Further, if D has just one syntax, then why add the word "new".  Any 
 constuctor will use the heap and doesn't need the memory deleted manually. 
 So why use a keyword that drums up visions of stack vs heap debates and 
 manual memory allocation?
 

You can allocate class objects on the heap if you wish using the 'auto' keyword.
Feb 14 2005
prev sibling parent Matthias Becker <Matthias_member pathlink.com> writes:
I've always wondered about the requirement of the word new in Java.  It 
appears Java (I don't know much about it) pretends there are no 
references/pointers to help the poor coder who can't handle it (so I've read 
as the reason):

   Airplane A = new Airplane();
   // work with A

   // Make a new Airplane for the following function
   Fly( new Airplane( bar, 3 ) );

    Airplane B;
    // dont' work with B yet or a run-time error occurs

So, with such an emphasis on "no pointers" and coddling the pre-school 
coder, why the use of the word new?  It feels very pointer'ish to me. 
Forgetting it would cause a strange thing called a bad reference.  Scary! 
Why not

   Airplane A;
   // use default airplane

Why? Why isn't that a null-Reference? I'd prefer # Airplane A = Airplane();
   Airplane A = Airplane( 3 );
   // use specially constructed airplane
   // could have also just been a regular function like A = Init( 3 );

   // Make a new Airplane for the following function
   Fly( Airplane( bar, 3 ) );

This "new" practice has been copied to javascript, php, and now D.  Why? 
And before you hit me up with an efficiency issue, well OK, but these 
languages aren't bastions of efficiency and so why leave a possible run-time 
error hanging?

Feb 11 2005