www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Even if Object.print isn't going to be removed for now, it ought

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
One of the patches here

digitalmars.D.bugs/3170

removes the print method from class Object.  Walter seems to be 
hesitating to put it in.

It isn't clear to what extent removing it would break existing code. 
However, it's certainly time to deprecate it IMO.

The patch I've just posted here

digitalmars.D.bugs/4368

has the by-product of cutting out the use of Object.print that I know of 
(maybe there are others).

It isn't clear why Object.print exists when we have Object.toString.  If 
a program wants to output the string representation of something, it can 
use .toString directly, which is much more versatile.  While in theory 
print could be overridden e.g. to show more information than would 
appear in the toString, this isn't the way to do it.

The problem is that Object.print gives the application no control over 
what to output to.  Even when faced with the same class, different 
applications (or indeed parts of the same application) might want to 
write the data to stdout, stderr, a log file or a GUI window, just to 
name a few possibilities.  A single .print method with no parameters 
doesn't give the class user the choice.

If a class designer wants to provide a means of generating 'long' output 
distinct from the .toString behaviour, it can provide its own method, 
maybe called toLongString or something similar.  This would simply 
return the 'long' output and let the caller do what it wants with it. 
Then an application that wants access to this output, either to output 
it to whatever or to parse/manipulate it, can call this method.  Then, 
the only question that remains is whether toLongString should be in 
Object.  I personally don't see any point at the moment in putting it in 
... but does anyone?...

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on 
the 'group where everyone may benefit.
Jun 20 2005
next sibling parent clayasaurus <clayasaurus gmail.com> writes:
Stewart Gordon wrote:
 One of the patches here
 
 digitalmars.D.bugs/3170
 
 removes the print method from class Object.  Walter seems to be 
 hesitating to put it in.
 
 It isn't clear to what extent removing it would break existing code. 
 However, it's certainly time to deprecate it IMO.
 
 The patch I've just posted here
 
 digitalmars.D.bugs/4368
 
 has the by-product of cutting out the use of Object.print that I know of 
 (maybe there are others).
 
 It isn't clear why Object.print exists when we have Object.toString.  If 
 a program wants to output the string representation of something, it can 
 use .toString directly, which is much more versatile.  While in theory 
 print could be overridden e.g. to show more information than would 
 appear in the toString, this isn't the way to do it.
 
 The problem is that Object.print gives the application no control over 
 what to output to.  Even when faced with the same class, different 
 applications (or indeed parts of the same application) might want to 
 write the data to stdout, stderr, a log file or a GUI window, just to 
 name a few possibilities.  A single .print method with no parameters 
 doesn't give the class user the choice.
 
 If a class designer wants to provide a means of generating 'long' output 
 distinct from the .toString behaviour, it can provide its own method, 
 maybe called toLongString or something similar.  This would simply 
 return the 'long' output and let the caller do what it wants with it. 
 Then an application that wants access to this output, either to output 
 it to whatever or to parse/manipulate it, can call this method.  Then, 
 the only question that remains is whether toLongString should be in 
 Object.  I personally don't see any point at the moment in putting it in 
 ... but does anyone?...
 
 Stewart.
 

I've used it for... int main() { try { throw new Exception("An Exception Has Occured!"); } catch (Exception e) { e.print(); } return 0; } But I guess I could use writefln(e.toString); instead
Jun 20 2005
prev sibling next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message 
news:d965hk$lc2$1 digitaldaemon.com...

I totally agree with everything you said.  However, there is a problem with 
interfacing with classes in older libs.  Since .print() is in EVERY class in 
D, it is part of the vtable.  Removing the .print() function would cause 
interfaces to not work to the older libs anymore, as the vtable would be off 
for just about every function.  The libs would have to be recompiled with 
the new Object base class.  It should be deprecated, at least. 
Jun 20 2005
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d965hk$lc2$1 digitaldaemon.com>, Stewart Gordon says...
One of the patches here

digitalmars.D.bugs/3170

removes the print method from class Object.  Walter seems to be 
hesitating to put it in.

It isn't clear to what extent removing it would break existing code. 
However, it's certainly time to deprecate it IMO.

I did this a while back in Ares, and I can think of one one reason for keeping print() in place: it facilitates displaying meaningful error messages when exceptions are thrown in an out of memory condition. But were this sufficient reason to keep it, I'd vote for moving it into Exception and dropping it from Object. Sean
Jun 20 2005
next sibling parent reply Stewart Gordon <Stewart_member pathlink.com> writes:
In article <d9702j$196k$1 digitaldaemon.com>, Sean Kelly says...
<snip>
 I did this a while back in Ares, and I can think of one one reason 
 for keeping print() in place: it facilitates displaying meaningful 
 error messages when exceptions are thrown in an out of memory 
 condition.  But were this sufficient reason to keep it, I'd vote 
 for moving it into Exception and dropping it from Object.

Huh? What do you mean by this? Stewart.
Jun 20 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <d971rm$1an0$1 digitaldaemon.com>, Stewart Gordon says...
In article <d9702j$196k$1 digitaldaemon.com>, Sean Kelly says...
<snip>
 I did this a while back in Ares, and I can think of one one reason 
 for keeping print() in place: it facilitates displaying meaningful 
 error messages when exceptions are thrown in an out of memory 
 condition.  But were this sufficient reason to keep it, I'd vote 
 for moving it into Exception and dropping it from Object.

Huh? What do you mean by this?

It's not uncommon for toString to allocate memory for the returned string, while print just dumps the info to stderr. For system errors, allocating memory before they've been handled is a risky proposition. But upon reflection I see no reason not to just require such exceptions to not allocate memory in their toString methods and if the user attempts to manipulate the string returned by toString that's their problem. I just cleaned up the Ares code with this in mind. Sean
Jun 20 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Sean Kelly wrote:
<snip>
 It's not uncommon for toString to allocate memory for the returned string,
while
 print just dumps the info to stderr.  For system errors, allocating memory
 before they've been handled is a risky proposition. 

This implies that it may be a Bad Thing to allocate memory for the returned string before throwing the exception. But if OTOH it's during the error recovery that this happens (which tends to be so anyway, if the toString method generates the string on the fly), then by this time some pointers into the GC heap may have gone out of scope and so there may be some memory left. And forcing the programmer to duplicate effort by maintaining toString and print in parallel might not be the Right Thing - indeed it could be a source of bugs.
 But upon reflection I see
 no reason not to just require such exceptions to not allocate memory in their
 toString methods and if the user attempts to manipulate the string returned by
 toString that's their problem.  I just cleaned up the Ares code with this in
 mind.

If a class is going to use D library functions to generate an exception string, it's not unlikely that some memory'll be allocated in the process. And even if you use C functions, you'll still need somewhere to put it. And so how would generation of a personalised error string work at all? I guess it's a matter of what kinds of errors are likely to occur in the process of recovering from an OutOfMemoryException. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 21 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <d98nav$2m10$1 digitaldaemon.com>, Stewart Gordon says...
Sean Kelly wrote:
<snip>
 It's not uncommon for toString to allocate memory for the returned string,
while
 print just dumps the info to stderr.  For system errors, allocating memory
 before they've been handled is a risky proposition. 

This implies that it may be a Bad Thing to allocate memory for the returned string before throwing the exception. But if OTOH it's during the error recovery that this happens (which tends to be so anyway, if the toString method generates the string on the fly), then by this time some pointers into the GC heap may have gone out of scope and so there may be some memory left.

True enough.
And forcing the programmer to duplicate effort by maintaining toString 
and print in parallel might not be the Right Thing - indeed it could be 
a source of bugs.

Good point.
If a class is going to use D library functions to generate an exception 
string, it's not unlikely that some memory'll be allocated in the 
process.  And even if you use C functions, you'll still need somewhere 
to put it.  And so how would generation of a personalised error string 
work at all?

It wouldn't. But I think this is acceptable for system errors--at least at the throw site. When caught, the user could call a function to get a more detailed description if possible, like what happens in Windows code. Unless the error thrown was an OutOfMemoryError, this is quite likely to work. And as you say above, it may even work for OutOfMemory, since memory may have been released during stack unrolling. Sean
Jun 21 2005
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Sean Kelly wrote:
<snip>
 If a class is going to use D library functions to generate an 
 exception string, it's not unlikely that some memory'll be 
 allocated in the process.  And even if you use C functions, you'll 
 still need somewhere to put it.  And so how would generation of a 
 personalised error string work at all?

It wouldn't. But I think this is acceptable for system errors--at least at the throw site. When caught, the user could call a function to get a more detailed description if possible, like what happens in Windows code.

So every system error would have a constant (or generated in advance) error string, but other errors can have made-to-measure ones?
 Unless the error thrown was an OutOfMemoryError, this is quite likely 
 to work.  And as you say above, it may even work for OutOfMemory, 
 since memory may have been released during stack unrolling.

But we can't rely on this. Moreover, what specific information about an OutOfMemoryException (as it's called now) could we feasibly extract? And considering that there's only one pseudo-instance of OutOfMemoryException, which is thrown each time.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 21 2005
parent Sean Kelly <sean f4.ca> writes:
In article <d999f0$6dc$1 digitaldaemon.com>, Stewart Gordon says...
Sean Kelly wrote:
<snip>
 If a class is going to use D library functions to generate an 
 exception string, it's not unlikely that some memory'll be 
 allocated in the process.  And even if you use C functions, you'll 
 still need somewhere to put it.  And so how would generation of a 
 personalised error string work at all?

It wouldn't. But I think this is acceptable for system errors--at least at the throw site. When caught, the user could call a function to get a more detailed description if possible, like what happens in Windows code.

So every system error would have a constant (or generated in advance) error string, but other errors can have made-to-measure ones?

I don't know that it's necessary for non-system errors to be so careful. They would likely be thrown as a result of some logic failure, and it would be unlikely for this to coincide with an out of memory condition (without an OutOfMemoryError being thrown first). That said, there is a group in the C++ camp that says no DMA should ever occur at an exception throw site, because You Never Know. I think this is a fair statement, but then I wonder why std::runtime_error carried a std::string with it. Also, as classes in D do not have value semantics, it's difficult to throw an exception without any DMA at all. And if you're allocating memory for an exception, why not an error message as well?
 Unless the error thrown was an OutOfMemoryError, this is quite likely 
 to work.  And as you say above, it may even work for OutOfMemory, 
 since memory may have been released during stack unrolling.

But we can't rely on this. Moreover, what specific information about an OutOfMemoryException (as it's called now) could we feasibly extract?

None. An OutOfMemory error in D is thrown from the GC, so we don't even have a file/line number to carry.
And considering that there's only one pseudo-instance of 
OutOfMemoryException, which is thrown each time....

Yup. The other system errors typically carry file and line numbers, but OutOfMemoryError is just that. All you can really do is identify the error and try to free some memory, or just abort. Sean
Jun 21 2005
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Sean Kelly wrote:
<snip>
 I did this a while back in Ares, and I can think of one one reason
 for keeping print() in place: it facilitates displaying meaningful
 error messages when exceptions are thrown in an out of memory
 condition.  But were this sufficient reason to keep it, I'd vote for
 moving it into Exception and dropping it from Object.

Further to the discussion we've just had, even if there is a reason to keep it, there's no reason it should remain in its current form. As I said in my original post:
 The problem is that Object.print gives the application no control over 
 what to output to.


Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jun 29 2005