digitalmars.D - Type keyword ?
- Matthew Craig (75/75) Oct 08 2004 I'm still getting familiar with D so hopefully I'm not missing anything
- Ant (23/25) Oct 07 2004 yes: you got it all wrong that's why you need it.
- Matthew Craig (28/53) Oct 09 2004 Ok how would your design switch between interfaces i.e.
- Matthew Craig (9/73) Oct 09 2004 As Sjoerd has just pointed out I think templates are the answer to most ...
- Ant (39/76) Oct 09 2004 No, this is a simple school like case where
- Matthew Craig (78/138) Oct 09 2004 So what your saying is you should have
- Ant (9/24) Oct 09 2004 agree.
- John Reimer (9/16) Oct 09 2004 Ha Ha HA! :D Funny, Ant!
- Matthew Craig (5/21) Oct 09 2004 I've worked with people much more 'direct' he didn't even swear ;-)
- Ilya Minkov (21/31) Oct 13 2004 I haven't seen Ant being wrong on such questions. In fact, any runtime
- Matthew Craig (20/34) Oct 09 2004 Language design is always a balance between too little or too
- Sjoerd van Leent (56/67) Oct 09 2004 I am not quite convinced that the SDL_Surface and Surface types are the
- Ant (5/25) Oct 09 2004 where, where, how?
- Sjoerd van Leent (20/33) Oct 09 2004 Use class/interface templates:
- Matthew Craig (16/49) Oct 09 2004 I was thinking a combination of interface and template might be the answ...
- Lloyd Dupont (5/82) Oct 09 2004 just out of curiosity, is it private work or would you share it one day?
- Matthew Craig (10/120) Oct 09 2004 I'm just doing it for fun because I want to explore the D language, howe...
I'm still getting familiar with D so hopefully I'm not missing anything obvious. What I'm proposing is a keyword type only allowable in interfaces that basically means any type. I know what your thinking we want D to be a strongly typed language and this would negate type checking. Well not really as if I understand correctly interfaces are similar to pure virtual classes in that they have no implementation therefore type checking isn't necessary. And as I mentioned it would only be legal within interfaces. Consider the following code (forgive the use of pointers I'm still converting to D ;-)) // interface interface IGfx { byte* getScreen(); } // sdl interface alias SDL_Surface* Surface class ISDL : IGfx { SDL_Surface* screen; byte* getScreen() { return cast(byte*)screen; } } // gfx class Gfx : IGfx { byte* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(cast(Surface*)gfx.getScreen()); Now lets rewrite it with a type keyword to see the difference // interface interface IGfx { type getScreen(); } // sdl interface alias SDL_Surface Surface class ISDL : IGfx { SDL_Surface* screen; SDL_Surface* getScreen() { return screen; } } // gfx class Gfx : IGfx { Surface* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(gfx.getScreen()); Much clearer I think you'd agree The pros as I see it are a. Gain flexibility without losing any type checking b. Cleaner syntax c. Easier to add new interfaces The cons are a. Perhaps too flexible, consider that as you switched interfaces the return type of getScreen could change from a struct to a byte pointer. Still wouldn't have thought that's a really big deal. Any thoughts ?
Oct 08 2004
On Sat, 09 Oct 2004 01:26:34 +0100, Matthew Craig wrote:Any thoughts ?yes: you got it all wrong that's why you need it. alternativelly to your design: Screen is an interface that declares the flip method you'll have classes on sdl, ogl and dx packages that implement the Screen interface. you'll have methods on sdl, ogl and dx classes that return a Screen interface. the end result would be gfx.getScreen().flip(); "Much clearer I think you'd agree" :) I see your level of abstraction as inadequate, and the reponsabilities on the wrong places. why you still have the "currentInterface"?!... didn't we tell you to get rid of it? and don't use "alias", it's use should be retricted. in fact - in this case - replace alias by interface and you're almost there. Ant PS just trying to help (I tried before and always failed over the internet :(, but ask my coleagues: it works live, in person...)
Oct 07 2004
Ok how would your design switch between interfaces i.e. gfx.getScreen() // is that getScreen for OpenGL, SDL etc. that's why I still have currInterface plus it prevents me having to do gfx.getInterface.foo(); all the time and instead I can just say gfx.foo(); And how does your design return values don't you still have the same problems Surface screen = gfx.getScreen().getSurface(); a. So how would you declare Surface without using alias I thought it was just like typedef. b. And how do you get around the problem of interface blah { // don't know what type surface will be so use byte* byte* getSurface(); } class foo : blah { fooSurface* getSurface() {}; // error getSurface not implemented // could change to byte* but then need casting } Sorry if I'm being thick perhaps you could do a quick code snippet to explain what you mean. Thanks "Ant" <duitoolkit yahoo.ca> wrote in message news:pan.2004.10.08.04.00.25.923513 yahoo.ca...On Sat, 09 Oct 2004 01:26:34 +0100, Matthew Craig wrote:Any thoughts ?yes: you got it all wrong that's why you need it. alternativelly to your design: Screen is an interface that declares the flip method you'll have classes on sdl, ogl and dx packages that implement the Screen interface. you'll have methods on sdl, ogl and dx classes that return a Screen interface. the end result would be gfx.getScreen().flip(); "Much clearer I think you'd agree" :) I see your level of abstraction as inadequate, and the reponsabilities on the wrong places. why you still have the "currentInterface"?!... didn't we tell you to get rid of it? and don't use "alias", it's use should be retricted. in fact - in this case - replace alias by interface and you're almost there. Ant PS just trying to help (I tried before and always failed over the internet :(, but ask my coleagues: it works live, in person...)
Oct 09 2004
As Sjoerd has just pointed out I think templates are the answer to most of these problems as I mentioned I've been taught to be very wary of templates and never used them in production, however it sounds like D's template implementation is pretty solid. "Matthew Craig" <mwcraig btinternet.com> wrote in message news:ck8dkg$dkc$1 digitaldaemon.com...Ok how would your design switch between interfaces i.e. gfx.getScreen() // is that getScreen for OpenGL, SDL etc. that's why I still have currInterface plus it prevents me having to do gfx.getInterface.foo(); all the time and instead I can just say gfx.foo(); And how does your design return values don't you still have the same problems Surface screen = gfx.getScreen().getSurface(); a. So how would you declare Surface without using alias I thought it was just like typedef. b. And how do you get around the problem of interface blah { // don't know what type surface will be so use byte* byte* getSurface(); } class foo : blah { fooSurface* getSurface() {}; // error getSurface not implemented // could change to byte* but then need casting } Sorry if I'm being thick perhaps you could do a quick code snippet to explain what you mean. Thanks "Ant" <duitoolkit yahoo.ca> wrote in message news:pan.2004.10.08.04.00.25.923513 yahoo.ca...On Sat, 09 Oct 2004 01:26:34 +0100, Matthew Craig wrote:Any thoughts ?yes: you got it all wrong that's why you need it. alternativelly to your design: Screen is an interface that declares the flip method you'll have classes on sdl, ogl and dx packages that implement the Screen interface. you'll have methods on sdl, ogl and dx classes that return a Screen interface. the end result would be gfx.getScreen().flip(); "Much clearer I think you'd agree" :) I see your level of abstraction as inadequate, and the reponsabilities on the wrong places. why you still have the "currentInterface"?!... didn't we tell you to get rid of it? and don't use "alias", it's use should be retricted. in fact - in this case - replace alias by interface and you're almost there. Ant PS just trying to help (I tried before and always failed over the internet :(, but ask my coleagues: it works live, in person...)
Oct 09 2004
On Sat, 09 Oct 2004 11:31:53 +0100, Matthew Craig wrote:As Sjoerd has just pointed out I think templates are the answerNo, this is a simple school like case where the OO paradigma fits perfectly.again I see it differently from you. your Gfx class implementes the IGfx interface and just delegates to the currentInterface object. that's wrong. you should have one (or as many as you like simultaneasly) IGfx instanciated from any of the IGfx implementators. It's wrong to control which implementation is used from inside the IGfx object. you should have some other class to control it.Ok how would your design switch between interfaces i.e. gfx.getScreen() // is that getScreen for OpenGL, SDL etc.gfx *IS* the IGfx, does not contain a IGfx in your case it's both. See my answer to your other question. to switch implementations you just create a new IGfx instance from another IGfx implementator.that's why I still have currInterface plus it prevents me having to do gfx.getInterface.foo(); all the time and instead I can just say gfx.foo(); And how does your design return values don't you still have the same problemswrong idea, it should be: interface Surface { Surface flip(); int getWidth(); int getHeight(); void whatever(); } interface Screen : Surface { void whatever(); } (of course I don't know the details of Surface and Screen so that might be completly of) we don't know how Surface is implemented at the IGfx level. the IGfx only knows that surface can be fliped, has a width and a height and can do whatever. You don't expose the details of surface outside of it's implementators. don't go with the templates, it's wrong here. don't use templates until you fully get the OO with interfaces, then do who you feel it's better.Surface screen = gfx.getScreen().getSurface(); a. So how would you declare Surface without using alias I thought it was just like typedef. b. And how do you get around the problem of interface blah { // don't know what type surface will be so use byte* byte* getSurface(); }if you need to use alias and cast something went wrong somewhere.class foo : blah { fooSurface* getSurface() {}; // error getSurface not implemented // could change to byte* but then need casting }try to see if that enough, again don't use templates for this case. AntSorry if I'm being thick perhaps you could do a quick code snippet to explain what you mean.
Oct 09 2004
"Ant" <duitoolkit yahoo.ca> wrote in message news:pan.2004.10.09.15.43.14.581136 yahoo.ca...On Sat, 09 Oct 2004 11:31:53 +0100, Matthew Craig wrote:So what your saying is you should have IGfx gfx; IGfx gfxSdl = new ISDL(); IGfx gfxOpenGL = new IOpenGL(); and to switch you assign to gfx i.e. gfx = gfxSdl; fair enough and you agree another class could control the switching right, well surely it would look like the one I've got that your not impressed with enum GfxInterfaces { OpenGL } class Gfx { // Pointer to selected interface IGfx currInterface; // Available interfaces IGfx availableInterfaces[GfxInterfaces.max]; // Constructor this() { for ( int i = 0; i < GfxInterfaces.max; i++ ) { switch(i) { case GfxInterfaces.OpenGL : { availableInterfaces[i] = new IOpenGL(); } break; default : break; } } } void SwitchInterface(GfxInterfaces desiredInterface) { currInterface = availableInterfaces[desiredInterface]; } } I think what's thrown you is that i had class Gfx : IGfx which I agree is unnecessary if not plain wrong.As Sjoerd has just pointed out I think templates are the answerNo, this is a simple school like case where the OO paradigma fits perfectly.again I see it differently from you. your Gfx class implementes the IGfx interface and just delegates to the currentInterface object. that's wrong. you should have one (or as many as you like simultaneasly) IGfx instanciated from any of the IGfx implementators. It's wrong to control which implementation is used from inside the IGfx object. you should have some other class to control it.Ok how would your design switch between interfaces i.e. gfx.getScreen() // is that getScreen for OpenGL, SDL etc.I hear what your saying here about it being a text book case of OO design, encapsulate the surface and you should never need to get hold of it yourself and muck about with it (hence breaking the encapsulation) however the problem I find with text book design is it often causes frustration in the real world. I totally agree that the surface should be encapsulated away and you should try not to mess with it directly as much as possible, however theres a good chance at some point your going to want to just get hold of the raw data. Imagine your using someone elses library lets say it handles buffers. It's a great library and you've used it for a while and all is well until you suddenly wish it had another function. If it's not an open source project your only option is to request the author adds the function to his library however if it has a function such as getRawBuffer then at least you can pull out the raw data work on it in your function and put it back. If your an OO purist you'll no doubt argue all day that this is a terrible thing to do and you should find a better way of doing it, but it works and D being a practical language for practical people should allow you to do it without too much fuss IMHO after all that's why you have pointers it's a case of don't use them unless you have to but they're there if you really need them. In which case I think my original suggestion may still be valid.wrong idea, it should be: interface Surface { Surface flip(); int getWidth(); int getHeight(); void whatever(); } interface Screen : Surface { void whatever(); } (of course I don't know the details of Surface and Screen so that might be completly of) we don't know how Surface is implemented at the IGfx level. the IGfx only knows that surface can be fliped, has a width and a height and can do whatever. You don't expose the details of surface outside of it's implementators. don't go with the templates, it's wrong here. don't use templates until you fully get the OO with interfaces, then do who you feel it's better.Surface screen = gfx.getScreen().getSurface(); a. So how would you declare Surface without using alias I thought it was just like typedef. b. And how do you get around the problem of interface blah { // don't know what type surface will be so use byte* byte* getSurface(); }You still haven't mentioned what's so bad about using alias it just looks like typedef to me *shrugs*if you need to use alias and cast something went wrong somewhere.class foo : blah { fooSurface* getSurface() {}; // error getSurface not implemented // could change to byte* but then need casting }I think I got your point ;-)try to see if that enough, again don't use templates for this case.Sorry if I'm being thick perhaps you could do a quick code snippet to explain what you mean.Ant
Oct 09 2004
On Sat, 09 Oct 2004 21:17:05 +0100, Matthew Craig wrote:fair enough and you agree another class could control the switching right,of course.I think what's thrown you is that i had class Gfx : IGfx which I agree is unnecessary if not plain wrong.agree.Imagine your using someone elses library lets say it handles buffers. It's a great library and you've used it for a while and all is well until you suddenly wish it had another function.doesn't that shows your design to be faulty or incomplete? ;) but I agree the raw structures should be made available some how.If your an OO puristoh!... I see you're new here :)I think I got your point ;-)I think you did! Ant
Oct 09 2004
Ha Ha HA! :D Funny, Ant! Matthew, it may take awhile to get used to Ant's... err... style of critiquing, but Ant's okay. ;-) Although, I think Ant's going to have to eventually drop his notorious "English-is-my-second-language" excuse for being so direct with people. I'm beginning to think that he has become somewhat adept with the language now. :) Later, JohnIf your an OO puristoh!... I see you're new here :)
Oct 09 2004
I've worked with people much more 'direct' he didn't even swear ;-) I'm all for good constructive criticism it's how you separate the chaff from the wheat so to speak. "John Reimer" <brk_6502 NOSP_AM.yahoo.com> wrote in message news:ck9ugl$1cc9$1 digitaldaemon.com...Ha Ha HA! :D Funny, Ant! Matthew, it may take awhile to get used to Ant's... err... style of critiquing, but Ant's okay. ;-) Although, I think Ant's going to have to eventually drop his notorious "English-is-my-second-language" excuse for being so direct with people. I'm beginning to think that he has become somewhat adept with the language now. :) Later, JohnIf your an OO puristoh!... I see you're new here :)
Oct 09 2004
John Reimer schrieb::>oh!... I see you're new here :)Ha Ha HA! :D Funny, Ant!Matthew, it may take awhile to get used to Ant's... err... style of critiquing, but Ant's okay. ;-)I haven't seen Ant being wrong on such questions. In fact, any runtime discrimination using switch or if statements is very much slower than function pointers, and OO provides a very nice wrapper for these. So OO is very applicable where performance engeneering comes into play, to a certain degree of course.Although, I think Ant's going to have to eventually drop his notorious "English-is-my-second-language" excuse for being so direct with people. I'm beginning to think that he has become somewhat adept with the language now. :)I think it doesn't really matter. I live in a country where i day for day speak in my third (or was it fourth?) language, and almost noone notices that i could be a foreigner. :> So i started thinking up excuses for myself, but i don't think they limit themselves to my personality. * I have bipolar disorder. Leave me alone! ELSE I SCRREAM! * Hey, me comes from south! Let us *hug* each other and then nothing was ever wrong anyway! * I have multiple sclerosis. What did you just say? What's up anyway? Don't hesitate to add more. In fact, over these all years i have not simply been too harsh to some people, i have even offended some due to some strange condition of mine combined with ignorance. May those forgive me. -eye/photoAllergics
Oct 13 2004
Language design is always a balance between too little or too much flexibility. C++ has loads of flexibility (too much) which is the cause of its popularity and ultimately its (probable) demise. However in aiming to reduce c++'s flexibility care needs to be taken not to overshoot the mark. I'm not saying D is one way or the other yet, I've not used it long enough to even begin to judge. As you can see from my initial post it is possible however you have to make quite a mess to do it. IMHO the type keyword I suggested would prevent you being penalised for doing this and give it a touch more flexibility. Just a thought.Imagine your using someone elses library lets say it handles buffers. It's a great library and you've used it for a while and all is well until you suddenly wish it had another function.doesn't that shows your design to be faulty or incomplete? ;) but I agree the raw structures should be made available some how.I sure am, there's an interesting line in my Game Programming Gems book that goes "Game programmers are a slightly different breed than the typical application programmer, because their work is always expected to be cutting edge, pushing hardware constraints to the limit, game developers tend to be much more willing to bend or even break traditional programming design rules." Guess that rules me out of the purist camp ;-)If your an OO puristoh!... I see you're new here :)I think I got your point ;-)I think you did! Ant
Oct 09 2004
Ant wrote:On Sat, 09 Oct 2004 11:31:53 +0100, Matthew Craig wrote:I am not quite convinced that the SDL_Surface and Surface types are the same type. I think it is imported from a header file or something like that. If so, You can't use the standard OO paradigma (although it seems the most obvious way). At the other hand, it is possible to wrap up SDL_Surface and Surface in their own wrapper classes. This would reinstantiate the use of full blown OO programming. Were I previously mentioned thay (be it lazy) templated behaviour, it is very well possible to rewrite it to full OO: ----- *PREVIOUS* ----- interface Graphics(T) { T getScreen(); } class SDL : Graphics(SDLSurface) { SDLSurface screen; SDLSurface getScreen() {...} } class OpenGL : Graphics(Surface) { Surface screen; Surface getScreen() {...} } ----- *NEW* ----- interface Graphics { Surface getScreen(); } interface Surface { // ... generic surface methods } class SDLSurface : Surface { SDL_Surface instanceSDL; // ... overridden surface methods from the interface } class OpenGLSurface : Surface { OpenGL_Surface instanceOpenGL; // ... overridden surface methods from the interface } class SDL : Graphics { Surface screen; this() { screen = new SDLSurface(); } Surface getScreen() {...} } class OpenGL : Graphics { Surface screen; this() { screen = new OpenGLSurface(); } Surface getScreen() {...} } There are even much better solutions to this problem, but it is proven that both template programming and full OO programming can be used. It's up to you though. Regards, SjoerdAs Sjoerd has just pointed out I think templates are the answerNo, this is a simple school like case where the OO paradigma fits perfectly.
Oct 09 2004
On Sat, 09 Oct 2004 22:56:11 +0200, Sjoerd van Leent wrote:Ant wrote:It doesn't look that bad, in fact...On Sat, 09 Oct 2004 11:31:53 +0100, Matthew Craig wrote:I am not quite convinced that the SDL_Surface and Surface types are the same type.As Sjoerd has just pointed out I think templates are the answerNo, this is a simple school like case where the OO paradigma fits perfectly.There are even much better solutions to this problem,where, where, how?but it is proven that both template programming and full OO programming can be used. It's up to you though.yes, and now he has a choice. Ant
Oct 09 2004
Matthew Craig wrote:I'm still getting familiar with D so hopefully I'm not missing anything obvious. What I'm proposing is a keyword type only allowable in interfaces that basically means any type. I know what your thinking we want D to be a strongly typed language and this would negate type checking. Well not really as if I understand correctly interfaces are similar to pure virtual classes in that they have no implementation therefore type checking isn't necessary. And as I mentioned it would only be legal within interfaces.Use class/interface templates: This should make the thing better to read. And it is legal D. One last note, please use the D convention. It makes terrible reading with all those useless underscores and prefixes/postfixes. Regards, Sjoerd
Oct 09 2004
I was thinking a combination of interface and template might be the answer I'll give it a go. I've never really got stuck into templates before because the c++ STL was never considered 'fit for production' where I've worked however D's looks much better. Sorry about not using D convention (old habits die hard) however I didn't use any underscores the only ones used were from the SDL library which I can't change ;-) I imagine there will be a fair bit of 'hybrid' C/D code around until more libraries are ported to D. Thanks "Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ck8cd4$cm0$1 digitaldaemon.com...Matthew Craig wrote:basicallyI'm still getting familiar with D so hopefully I'm not missing anything obvious. What I'm proposing is a keyword type only allowable in interfaces thatwithinmeans any type. I know what your thinking we want D to be a strongly typed language and this would negate type checking. Well not really as if I understand correctly interfaces are similar to pure virtual classes in that they have no implementation therefore type checking isn't necessary. And as I mentioned it would only be legalinterfaces.Use class/interface templates: This should make the thing better to read. And it is legal D. One last note, please use the D convention. It makes terrible reading with all those useless underscores and prefixes/postfixes. Regards, Sjoerd
Oct 09 2004
just out of curiosity, is it private work or would you share it one day? loks pretty .... mesmerizing? (I'm not sure it's the right word, I'm only a poor french in a remote country) "Matthew Craig" <mwcraig btinternet.com> wrote in message news:ck7b7l$2kh0$1 digitaldaemon.com...I'm still getting familiar with D so hopefully I'm not missing anything obvious. What I'm proposing is a keyword type only allowable in interfaces that basically means any type. I know what your thinking we want D to be a strongly typed language and this would negate type checking. Well not really as if I understand correctly interfaces are similar to pure virtual classes in that they have no implementation therefore type checking isn't necessary. And as I mentioned it would only be legal within interfaces. Consider the following code (forgive the use of pointers I'm still converting to D ;-)) // interface interface IGfx { byte* getScreen(); } // sdl interface alias SDL_Surface* Surface class ISDL : IGfx { SDL_Surface* screen; byte* getScreen() { return cast(byte*)screen; } } // gfx class Gfx : IGfx { byte* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(cast(Surface*)gfx.getScreen()); Now lets rewrite it with a type keyword to see the difference // interface interface IGfx { type getScreen(); } // sdl interface alias SDL_Surface Surface class ISDL : IGfx { SDL_Surface* screen; SDL_Surface* getScreen() { return screen; } } // gfx class Gfx : IGfx { Surface* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(gfx.getScreen()); Much clearer I think you'd agree The pros as I see it are a. Gain flexibility without losing any type checking b. Cleaner syntax c. Easier to add new interfaces The cons are a. Perhaps too flexible, consider that as you switched interfaces the return type of getScreen could change from a struct to a byte pointer. Still wouldn't have thought that's a really big deal. Any thoughts ?
Oct 09 2004
I'm just doing it for fun because I want to explore the D language, however if I get to a point where I feel the community would find what I'm doing useful I would happily contribute it back. I wouldn't hold your breath though I've still got lots to learn ;-) "Lloyd Dupont" <ld NewsAccount.galador.net> wrote in message news:ck8kl3$i31$1 digitaldaemon.com...just out of curiosity, is it private work or would you share it one day? loks pretty .... mesmerizing? (I'm not sure it's the right word, I'm onlyapoor french in a remote country) "Matthew Craig" <mwcraig btinternet.com> wrote in message news:ck7b7l$2kh0$1 digitaldaemon.com...withinI'm still getting familiar with D so hopefully I'm not missing anything obvious. What I'm proposing is a keyword type only allowable in interfaces that basically means any type. I know what your thinking we want D to be a strongly typed language and this would negate type checking. Well not really as if I understand correctly interfaces are similar to pure virtual classes in that they have no implementation therefore type checking isn't necessary. And as I mentioned it would only be legalpointer.interfaces. Consider the following code (forgive the use of pointers I'm still converting to D ;-)) // interface interface IGfx { byte* getScreen(); } // sdl interface alias SDL_Surface* Surface class ISDL : IGfx { SDL_Surface* screen; byte* getScreen() { return cast(byte*)screen; } } // gfx class Gfx : IGfx { byte* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(cast(Surface*)gfx.getScreen()); Now lets rewrite it with a type keyword to see the difference // interface interface IGfx { type getScreen(); } // sdl interface alias SDL_Surface Surface class ISDL : IGfx { SDL_Surface* screen; SDL_Surface* getScreen() { return screen; } } // gfx class Gfx : IGfx { Surface* getScreen() { return currInterface.getScreen(); } } // main gfx.FlipScreen(gfx.getScreen()); Much clearer I think you'd agree The pros as I see it are a. Gain flexibility without losing any type checking b. Cleaner syntax c. Easier to add new interfaces The cons are a. Perhaps too flexible, consider that as you switched interfaces the return type of getScreen could change from a struct to a byteStill wouldn't have thought that's a really big deal. Any thoughts ?
Oct 09 2004