www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - toString in Object

reply Derek <derek psych.ward> writes:
Walter,
can you please confirm or deny that 'char[] toString()' will be removed
from the Object class. And if so, when?

Because it exists, I cannot create a 'dchar[] toString()' in my classes, as
I get the dreaded "overrides but is not covariant with
object.Object.toString" message!

-- 
Derek
Melbourne, Australia
Feb 19 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
Hi, Derek,

I guess that toUTF32() or toDChars() names would be better...
Strictly speaking there are no such entity as String in D so name toString 
is misleading a bit.
IMHO.

Andrew Fedoniouk.
http://terrainformatica.com


"Derek" <derek psych.ward> wrote in message 
news:1h9qh6scvt40n$.1mp0213bpkkpm.dlg 40tude.net...
 Walter,
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?

 Because it exists, I cannot create a 'dchar[] toString()' in my classes, 
 as
 I get the dreaded "overrides but is not covariant with
 object.Object.toString" message!

 -- 
 Derek
 Melbourne, Australia 
Feb 19 2005
next sibling parent Derek <derek psych.ward> writes:
On Sat, 19 Feb 2005 22:25:03 -0800, Andrew Fedoniouk wrote:

 Hi, Derek,
 
 I guess that toUTF32() or toDChars() names would be better...
 Strictly speaking there are no such entity as String in D so name toString 
 is misleading a bit.
 IMHO.
LOL, yes I guess that is just an opinion. But true, there is no 'official' formal string type or class, and even in spite of that, strings are widely used in the phobos library and most all our programs. So I think its okay to talk about the informal string types that are in use with D programming. I suspect, that when D was just a twinkle in Walter's eye, the char[] type was the only available string type (borrowed no doubt from C), and it was not until later that wchar[] and dchar[] arrived. But by that time, char[] was being assumed as the common type of string and thus nearly all of phobos assumes char[]. Yes, it is annoying that we don't have an official string type, but it is not a death sentence for the language. It just means that instead of the compiler doing some of the work for us, we coders need to do a bit more. Oh well, maybe one day Walter will give in and try to help out us poor coders a bit. -- Derek Melbourne, Australia
Feb 19 2005
prev sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
What I'd personally like to see is something similar to what Sofu's 
Value class exposes.  It could still 'default' to class name.









But maybe I'm crazy.

-- Chris S
Feb 20 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <cvajck$75n$1 digitaldaemon.com>, Chris Sauls says...
What I'd personally like to see is something similar to what Sofu's 
Value class exposes.  It could still 'default' to class name.









But maybe I'm crazy.

-- Chris S
What is Sofu? One issue with having all three functions in Object is that the class author has to make sure they don't return different values from the three versions. That looks like it will be a source of bugs and confusion. Plus it makes the API surface area larger. Maybe we just need to add wchar toWString(Object o){ return toUTF16(o.toString()); } dchar toDString(Object o){ return toUTF32(o.toString()); } to std.string. That way class authors don't have to worry about which the user wants to use in the end. Let me add, though, that std.string defines things like toString(int x) and toString(double x) and it would be a waste IMO to have two more versions of all of those just to save people from typing toUTF16 or toUTF32. -Ben
Feb 20 2005
next sibling parent Chris Sauls <ibisbasenji gmail.com> writes:
Ben Hinkle wrote:
 What is Sofu?
Sofu is a textual data file format. It has its uses. http://sofu.sourceforge.net/index.html
 One issue with having all three functions in Object is that the class author
has
 to make sure they don't return different values from the three versions.
Note that in my example, Object.toUTF16() and Object.toUTF32() just transcode and return the result of Object.toUTF8() -- my point? If I just need basic functionality for my class's toUTF*() then I only have to override one function. -- Chris S
Feb 20 2005
prev sibling next sibling parent reply Sebastian Beschke <s.beschke gmx.de> writes:
Ben Hinkle schrieb:
 What is Sofu?
A parser library for a data file format. http://sofu.sourceforge.net/ Still quite half-baked, I need to get some time to work on it again. :)
 Let me add, though, that std.string defines things like toString(int x) and
 toString(double x) and it would be a waste IMO to have two more versions of all
 of those just to save people from typing toUTF16 or toUTF32.
In applications that use wchar[] or dchar[] as the default in many places, additional toUTF*() calls can obfuscate the code considerably. Also, I think that wchar[] is probably the most efficient format for most strings. Just think of CJK languages. IIRC, their characters usually take up three code units in UTF-8 - more than in UTF-16. Add to that the fact that in the very near future most people using a computer will be Chinese... -Sebastian
Feb 20 2005
parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Sebastian Beschke wrote:

 In applications that use wchar[] or dchar[] as the default in many
 places, additional toUTF*() calls can obfuscate the code considerably.
 Also, I think that wchar[] is probably the most efficient format for
 most strings.
Java and Windows seem to agree with you... Walter, however, does not.
 Just think of CJK languages. IIRC, their characters
 usually take up three code units in UTF-8 - more than in UTF-16. Add to
 that the fact that in the very near future most people using a computer
 will be Chinese...
Well, it would still *work* with Chinese which is a (small) comfort ? And it does get a little silly after a while with "full" support... int mainUTF8(char[][] args) { } int mainUTF16(wchar[][] args) { } int mainUTF32(dchar[][] args) { } It's a lot easier to just live with char[], even if it's "slower". Note: DMD and Phobos also convert UTF-16 and UTF-32 to UTF-8 internally, in a lot of places. Sensitive areas have all three versions overloaded. --anders
Feb 20 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 20 Feb 2005 20:00:24 +0000 (UTC), Ben Hinkle  
<Ben_member pathlink.com> wrote:
 In article <cvajck$75n$1 digitaldaemon.com>, Chris Sauls says...
 What I'd personally like to see is something similar to what Sofu's
 Value class exposes.  It could still 'default' to class name.









 But maybe I'm crazy.

 -- Chris S
What is Sofu? One issue with having all three functions in Object is that the class author has to make sure they don't return different values from the three versions. That looks like it will be a source of bugs and confusion. Plus it makes the API surface area larger.
I agree, yuck.
 Maybe we just need to add
 wchar toWString(Object o){ return toUTF16(o.toString()); }
 dchar toDString(Object o){ return toUTF32(o.toString()); }
 to std.string. That way class authors don't have to worry about which  
 the user
 wants to use in the end.
It's a pity we can't overload on return type. Or can we.. if we force the programmer to be explicit about it? It would require return type to be considered in the name resolution system.. perhaps it's too big a change?
 Let me add, though, that std.string defines things like toString(int x)  
 and
 toString(double x) and it would be a waste IMO to have two more versions  
 of all
 of those just to save people from typing toUTF16 or toUTF32.
Agreed, they simply need to type: double d; dchar[] s; s = toUTF32(toString(d)); or, if we add "explicit transcoding" on cast: double d; dchar[] s; s = cast(dchar[])toString(d); or, if we add overload on return type: double d; dchar[] s; s = toString(d); Regan
Feb 20 2005
parent reply xs0 <xs0 xs0.com> writes:
 It's a pity we can't overload on return type. Or can we.. if we force 
 the  programmer to be explicit about it? It would require return type to 
 be  considered in the name resolution system.. perhaps it's too big a 
 change?
If the programmer needs to be explicit about it, isn't it just the same if you use two method names? :) xs0
Feb 20 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 20 Feb 2005 22:49:14 +0100, xs0 <xs0 xs0.com> wrote:
 It's a pity we can't overload on return type. Or can we.. if we force  
 the  programmer to be explicit about it? It would require return type  
 to be  considered in the name resolution system.. perhaps it's too big  
 a change?
If the programmer needs to be explicit about it, isn't it just the same if you use two method names? :)
Sure, as was shown in my examples. However it might be possible to require it only when it's indeterminate. Regan
Feb 20 2005
prev sibling parent reply Derek <derek psych.ward> writes:
On Sun, 20 Feb 2005 20:00:24 +0000 (UTC), Ben Hinkle wrote:

 In article <cvajck$75n$1 digitaldaemon.com>, Chris Sauls says...
What I'd personally like to see is something similar to what Sofu's 
Value class exposes.  It could still 'default' to class name.









But maybe I'm crazy.

-- Chris S
What is Sofu? One issue with having all three functions in Object is that the class author has to make sure they don't return different values from the three versions. That looks like it will be a source of bugs and confusion.
On the other hand, names like "toUTF16" and "toUTF32" specify the return data type in the name itself. So it is unlikely that coders would be confused enough to write a toUTF16 function that returned a 'real'.
 Plus it makes the API
 surface area larger. Maybe we just need to add
 wchar toWString(Object o){ return toUTF16(o.toString()); }
 dchar toDString(Object o){ return toUTF32(o.toString()); }
 to std.string. That way class authors don't have to worry about which the user
 wants to use in the end.
Now this argument has some weight. -- Derek Melbourne, Australia
Feb 20 2005
parent Ben Hinkle <Ben_member pathlink.com> writes:
In article <105fk737tg8h1.4qbrn36dqke$.dlg 40tude.net>, Derek says...
On Sun, 20 Feb 2005 20:00:24 +0000 (UTC), Ben Hinkle wrote:

 In article <cvajck$75n$1 digitaldaemon.com>, Chris Sauls says...
What I'd personally like to see is something similar to what Sofu's 
Value class exposes.  It could still 'default' to class name.









But maybe I'm crazy.

-- Chris S
What is Sofu? One issue with having all three functions in Object is that the class author has to make sure they don't return different values from the three versions. That looks like it will be a source of bugs and confusion.
On the other hand, names like "toUTF16" and "toUTF32" specify the return data type in the name itself. So it is unlikely that coders would be confused enough to write a toUTF16 function that returned a 'real'.
I meant for example,
Feb 20 2005
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek wrote:

 Walter,
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
 
 Because it exists, I cannot create a 'dchar[] toString()' in my classes, as
 I get the dreaded "overrides but is not covariant with
 object.Object.toString" message!
Why can't you just use char[] toString() with std.utf.toUTF8 ? IMHO, the method that really needs to die in Object is "print()" --anders
Feb 20 2005
next sibling parent reply Derek <derek psych.ward> writes:
On Sun, 20 Feb 2005 13:44:51 +0100, Anders F Björklund wrote:

 Derek wrote:
 
 Walter,
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
 
 Because it exists, I cannot create a 'dchar[] toString()' in my classes, as
 I get the dreaded "overrides but is not covariant with
 object.Object.toString" message!
Why can't you just use char[] toString() with std.utf.toUTF8 ?
I assume you mean I can code ... x = std.utf.toUTF32( myClass.toString() ); Of course I can, but that's not the point. In the general case, if the Object class contains *any* function, it means that no other class can contain a method with the same name that returns a different data type. And that is not all that reasonable, let alone polite Object behaviour.
 IMHO, the method that really needs to die in Object is "print()"
Oh yes, and there is reasonable arguments for removing the other offenders too. But for now, I'm unhappy about toString() only ever being allowed to return a char[]. -- Derek Melbourne, Australia
Feb 20 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek wrote:

Why can't you just use char[] toString() with std.utf.toUTF8 ?
I assume you mean I can code ... x = std.utf.toUTF32( myClass.toString() ); Of course I can, but that's not the point.
Okay, then I missed the point... Do you want to override methods with different return types ? Or do you just wish that D should default to UTF-32 instead of UTF-8 like now ? --anders
Feb 20 2005
parent reply Derek <derek psych.ward> writes:
On Sun, 20 Feb 2005 16:09:45 +0100, Anders F Björklund wrote:

 Derek wrote:
 
Why can't you just use char[] toString() with std.utf.toUTF8 ?
I assume you mean I can code ... x = std.utf.toUTF32( myClass.toString() ); Of course I can, but that's not the point.
Okay, then I missed the point...
That's okay. The point is, I wanted to use a function name that just happened to be in Object, but with a different return type. So Walter's choice of a specific function name has prevented anyone else using the same name with a different return type.
 Do you want to override
 methods with different return types ? 
Yes, but that is not the point either. The point is, to reword it yet again, Walter has cut off a set of method names; they are no longer available to be *freely* used by other class authors. The name 'toString' is just an example. I'm not actually talking about what toString() does or does not do. It is just an example of this situation.
Or do you just wish
 that D should default to UTF-32 instead of UTF-8 like now ?
I could live with that. For external storage UTF8 or UTF16 would be better, but for character manipulation, UTF32 is safer at the expense of extra RAM usage (IMHO). -- Derek Melbourne, Australia
Feb 20 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek wrote:

Okay, then I missed the point... 
 
 That's okay. The point is, I wanted to use a function name that just
 happened to be in Object, but with a different return type. So Walter's
 choice of a specific function name has prevented anyone else using the same
 name with a different return type.
Right. I was used to both, from Java (no return overloads, has Object.toString: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#toString())
 I could live with that. For external storage UTF8 or UTF16 would be better,
 but for character manipulation, UTF32 is safer at the expense of extra RAM
 usage (IMHO).
No argument there. (many functions in D uses a "char[]" / "dchar" combo, UTF-8 for storage and UTF-32 for looping and outputting characters, etc) --anders
Feb 20 2005
prev sibling parent reply Brad Anderson <brad dsource.dot.org> writes:
Anders F Björklund wrote:
 
 IMHO, the method that really needs to die in Object is "print()"
amen.
Feb 20 2005
parent =?ISO-8859-1?Q?Thomas_K=FChne?= <thomas-dloop kuehne.THISISSPAM.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Brad Anderson wrote:
| Anders F Björklund wrote:
|
|>
|> IMHO, the method that really needs to die in Object is "print()"
|
| amen.

Let the hunting season begin!

Thomas

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (MingW32)

iD8DBQFCGQYf3w+/yD4P9tIRApSZAJ9np1NTgUTc0N56Yvx0dH9CKDe1bQCfSsGA
Hwudc7OMzxPnNRCef3WP9vU=
=Jai9
-----END PGP SIGNATURE-----
Feb 20 2005
prev sibling next sibling parent reply "uframer" <uframer sina100.com.cn> writes:
"Derek" <derek psych.ward> 
??????:1h9qh6scvt40n$.1mp0213bpkkpm.dlg 40tude.net...
 Walter,
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?

 Because it exists, I cannot create a 'dchar[] toString()' in my classes, 
 as
 I get the dreaded "overrides but is not covariant with
 object.Object.toString" message!

 -- 
 Derek
 Melbourne, Australia
Oh, i'm tired of these chars(char wchar dchar).Why can't we just have "one" standard codepage, just like what java does? I mean the Object should only support Unicode, so as Andrew said, toUTF32() or toDchars() is really a good choice.And for D, unicode should be the mainstream, while others as utilities for compatibility .
Feb 20 2005
next sibling parent Sebastian Beschke <s.beschke gmx.de> writes:
uframer schrieb:
 Oh, i'm tired of these chars(char wchar dchar).Why can't we just have "one" 
 standard codepage, just like what java does? I mean the Object should only 
 support Unicode, so as Andrew said, toUTF32() or toDchars() is really a good 
 choice.And for D, unicode should be the mainstream, while others as 
 utilities for compatibility . 
The problem here is that char[], wchar[] and dchar[] are *all* unicode, but in different encodings. -Sebastian
Feb 20 2005
prev sibling parent reply =?UTF-8?B?VGhvbWFzIEvDvGhuZQ==?= writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

uframer wrote:
| Oh, i'm tired of these chars(char wchar dchar).Why can't we just have
"one"
| standard codepage, just like what java does?

What are the standard char types for Windows and Linux APIs?

Thomas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (MingW32)

iD8DBQFCGQaR3w+/yD4P9tIRAqx+AJwMzxBgF8Qs9s8uQT8baTnUg2hn2wCgqWA+
u1cIBy/rE5cWQX5Nu9t36RA=
=xJiW
-----END PGP SIGNATURE-----
Feb 20 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Thomas Kühne wrote:

 What are the standard char types for Windows and Linux APIs?
"wchar_t". They just differ on the implementation ;-) (in Phobos, it is located in std.c.stddef, by the way) A lot of of the legacy API just use "char", however... Which can be of any sign and any encoding, basically? --anders
Feb 20 2005
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
Am I REALLY this invisible??! I just posted the SAME THREAD yesterday! Yes, in fact, it's two down from this one!
Feb 20 2005
next sibling parent John Reimer <brk_6502 yahoo.com> writes:
On Sun, 20 Feb 2005 12:07:39 -0500, Jarrett Billingsley wrote:

 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
Am I REALLY this invisible??! I just posted the SAME THREAD yesterday! Yes, in fact, it's two down from this one!
No, I think the topic just has to be brought up over and over again before something is done about it. The more it's brought up by different people, the better, I guess. Nobody's out to ignore you personally. ;-)
Feb 20 2005
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Jarrett Billingsley wrote:

 Am I REALLY this invisible??!
 
 I just posted the SAME THREAD yesterday!  Yes, in fact, it's two down from 
 this one! 
No, it's not the same question... (even without the yelling) You asked: ("Remove Object.toString()?")
 will Object.toString() be removed?  The same information is available through 
 Object.classinfo.name, and it's really irritating to have to type 
 "std.string.toString" every time I want to use toString() in a class member 
 function. 
Derek asked: ("toString in Object")
 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
 
 Because it exists, I cannot create a 'dchar[] toString()' in my classes, as
 I get the dreaded "overrides but is not covariant with
 object.Object.toString" message!
None of these are really issues for removing Object.toString. (first one can use .toString, second can use char[] toString) I also think that toString() is *supposed* to return something readable, like it works in Java. And std.format seems to agree:
 	    case Mangle.Tclass:
 		vobject = va_arg!(Object)(argptr);
 		s = vobject.toString();
 		goto Lputstr;
That the default implementation doesn't, that's another issue... And better Phobos documentation would definitely be a big help. http://www.digitalmars.com/d/phobos.html:
 class Object
     All class objects in D inherit from Object.
 char[] toString()
     Convert Object to a human readable string.
Splitting toString into toUTF8/toUTF16/toUTF32 could of course be done, if performance is ever needed on the toString method ? --anders
Feb 20 2005
parent reply Derek <derek psych.ward> writes:
On Sun, 20 Feb 2005 21:43:59 +0100, Anders F Björklund wrote:

[snip]

 
 None of these are really issues for removing Object.toString.
 (first one can use .toString, second can use char[] toString)
Unless one wants to code 'dchar[]toString()' ;-)
 
 I also think that toString() is *supposed* to return something
 readable, like it works in Java. And std.format seems to agree:
 
 	    case Mangle.Tclass:
 		vobject = va_arg!(Object)(argptr);
 		s = vobject.toString();
 		goto Lputstr;
That the default implementation doesn't, that's another issue... And better Phobos documentation would definitely be a big help. http://www.digitalmars.com/d/phobos.html:
 class Object
     All class objects in D inherit from Object.
 char[] toString()
     Convert Object to a human readable string.
Yes, I think this is the crux of the reason that toString() is in Object. However, it is only partially achieving this aim, because the output, a char[], is still an UTF8 stream and will only fully display correctly on devices that understand UTF8 streams. However, as most of us only deal with English or simple Latin characters, this is not a big deal; pity about the other poor buggers ;-) I now realize that if I want to 'override' the return type in D, I need to place the return type information into the function name, like toUTF8, toUTF16, toUTF32. -- Derek Melbourne, Australia
Feb 20 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek wrote:

 However, it is only partially achieving this aim, because the output, a
 char[], is still an UTF8 stream and will only fully display correctly on
 devices that understand UTF8 streams. However, as most of us only deal with
 English or simple Latin characters, this is not a big deal; pity about the
 other poor buggers ;-)
D *only* supports input and output in UTF formats, so you'll have to catch up with the rest of us I'm afraid... (by using Unicode) It's possible to convert char[] into ubyte[] for legacy displays, but it's not something that's in the main language/lib by itself. There's decent support for wchar[] functions, if in the OS: See http://www.digitalmars.com/techtips/windows_utf.html
 I now realize that if I want to 'override' the return type in D, I need to
 place the return type information into the function name, like toUTF8,
 toUTF16, toUTF32.
Yup, that's how it works at the moment. "W" is a popular suffix for wchar[] versions of the char[] ones. It's either "Wide" or "Walter" :-) --anders
Feb 20 2005
prev sibling next sibling parent reply Derek <derek psych.ward> writes:
On Sun, 20 Feb 2005 12:07:39 -0500, Jarrett Billingsley wrote:

 can you please confirm or deny that 'char[] toString()' will be removed
 from the Object class. And if so, when?
Am I REALLY this invisible??!
Alternately, it could be that I didn't read your post before sending mine. I note that there is a mere 2 hour difference between the two posts - so like the old saying goes "great minds think alike" ;-) But I'm more than happy to acknowledge that you were the first raiser of this issue - I don't need the glory ;-)
 I just posted the SAME THREAD yesterday!  Yes, in fact, it's two down from 
 this one!
However, I do notice that the reasons for posting the similar messages are different. You are wanting to avoid having to specify the complete package.module name to disambiguate the toString() references, whereas I was wanting to create a version of toString() that returned dchar[] rather than char[]. I then when on to realize that *any* function that is declared in Object will prevent a same-named function in any another class from returning a different data type. And it is debatable whether that is such a good thing. -- Derek Melbourne, Australia
Feb 20 2005
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Derek wrote:

 I then when on to realize that *any* function that is declared in Object
 will prevent a same-named function in any another class from returning a
 different data type. And it is debatable whether that is such a good thing.
Well, it's not a bad thing if you actually *want* the method on Object. (assuming for a second that the current D method of separating methods that return different types by a suffix, is a satisfactory workaround) However, it does become a problem when it includes oldskool C functions with a high abuse factor (like printf) or methods whose implementations drag a lot of extra overhead into the D runtime library (like print)... And, of course, adding "bool" to object.d is just a traditional Hack. :) --anders
Feb 20 2005
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
Sorry, I'm just used to forums where posting a thread without looking for 
similar threads that have been posted before is nearly a sin.. It's just 
that this is not the first time that this has happened to me.  How about my 
module problems thread a few weeks ago?  The only people who replied were 
two guys having a pretty much OT conversation in the thread, and Walter 
asking me to clarify something, without actually acknowledging the rest of 
my post.  Then, a week or so later, I saw a few threads that talked about 
very similar things, and they sparked long, serious discussions. 
Feb 21 2005