February 11, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick | 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 > > |
February 11, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick | "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() ); |
February 11, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | 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. |
February 11, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Charlie Patterson | 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 |
February 11, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick | "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." |
February 13, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | 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 > > 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.. 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 |
February 13, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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.
|
February 14, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | 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 |
February 14, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick | >>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 |
February 14, 2005 Re: OT: Airplane A = new Airplane() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Charlie Patterson | 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) >> <snip> > > > 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. |
Copyright © 1999-2021 by the D Language Foundation