I don't suppose there's a way to extend types...
BlitzMax Forums/BlitzMax Beginners Area/I don't suppose there's a way to extend types...
| ||
Without "extending" them? Here's the problem: Mark's TList type doesn't have a method to swap two links in the list. I'd like to add a method to do this. I do not want to change the source to max however because that would be bad and get overwritten, etc. But I also have used the TList type throughought my code. If I were to make a new type using the Extends keyword to extend the list type, I'd have to go through all of my code and change it to use the new list type name instead, and I might miss some instances in one of my source files. Anyways I'd just rather not have to do this. It might be possible to do right now, but I'm thinking about a much bigger project what one might do in that case. So the ideal thing would be to have the ability to add methods to a type without actually making a new type. Like, use the same type name elsewhere in the code, add additional fields, and methods, and functions to that, and they are magically included in the original type. Cue people telling me that's not how OOP works and that convenience is the thing we sacrifice to the OOP god. |
| ||
clone the module to an own one and make sure you import that instead of brl.linkedlist That way it shouldn't be a problem. There is no other way unless you want to use the regular extend way I fear. |
| ||
If I were to make a new type using the Extends keyword to extend the list type, I'd have to go through all of my code and change it to use the new list type name instead No you won't. The old TList will still work as usual (as opposed to what you're suggesting). Like, use the same type name elsewhere in the code, add additional fields, and methods, and functions to that, and they are magically included in the original type. This might have worked in a script / interpreted language like Python (but it doesn't), or in a late bind language (like Java or C#, but it doesn't) but not in a early bind compiled language like BlitzMAX. Each object must have a well defined interface at link time. So the ideal thing would be to have the ability to add methods to a type without actually making a new type. Why would that be ideal? So you instance 50 lists of various objects. Then you decide you want a swaplinks function. Now the compiler at run-time has to go through every list in memory swapping out data structures and interfaces on the go, causeing all sorts of havok and wierd bugs, as things that at one time assumed one interface, now suddenly has another? Cue people telling me that's not how OOP works and that convenience is the thing we sacrifice to the OOP god. Convenience is what we get from OO, not what we sacrifice. Make your peace with spagetti code, you won't be needing it anymore. |
| ||
Yes you can extend TList and not have to change anything in your source, but are you really using that many "TList" references, an extended Type is no slower so you should probably get over your fears and start use TSwiftLists, they will automatically inherit any mods made to brl.LinkedList.Tlist.... Anyway, here is a version of TList extended with dreamora's version of Reverse to illustrate how you can replace TList with your own TList Strict Type TList Extends brl.LinkedList.TList Method Reverse() Local temp:TLink Local result:TList = New TList Local pLink:TLink= _head Local ppLink:TLink Print "dreamoras tlist" ' Let iterate point to tail pLink = _head._pred ppLink = pLink._pred result._head._succ = pLink result._head._succ._pred = result._head result._head._pred = firstlink() result._head._pred._succ = result._head temp = pLink pLink = ppLink ppLink = pLink._pred While pLink._value <> pLink temp._succ = pLink pLink._pred = temp temp = temp._succ pLink = ppLink ppLink = ppLink._pred Wend swap result End Method End Type Local l:TList=New TList l.AddLast "one" l.AddLast "two" l.AddLast "three" l.Reverse For Local a$=EachIn l Print a$ Next Print "done" |
| ||
"No you won't. The old TList will still work as usual (as opposed to what you're suggesting)." Yes, but I won't be able to use the new functionality unless I change all the types. "Now the compiler at run-time has to go through every list in memory swapping out data structures and interfaces on the go, causeing all sorts of havok and wierd bugs, as things that at one time assumed one interface, now suddenly has another?" If I could write a program to go through the source file and copy all the instances of a type into a single type at the start of the program before compiling it, then the compiler could too. You're talking about something much more complicated. Maybe types in a function overriding a global type or or something. I don't even know if Max can do those, but I've never used them. "Convenience is what we get from OO, not what we sacrifice." I beg to differ. It took me a week to write my sprite system in BlitzPlus. It took me a month to do it in Max. And even though I am now familiar with the basic concepts behind OOP it still takes me a lot longer to design pretty types with functions and methods in them. For example with procedural programming: "Hmm... I need a seletor which has four sprites that rotate around one in the middle. I'll just make an array of sprites and create them and voila done." With OOP: "Hmm... I need a seelector which has four sprites that rotate around one in the middle... I guess I should have a global array in my type, but what if I want to select multiple objects? Maybe I should have a field array? I guess I need a create function now... Should I have the create function call a New method, or just have a new method? If I just have a new function I can't pass parameters in the future. But a new method isn't neccessary if I'm never going to allocate new selectors with ThisSelector = New Selector. Hm.... Well crap I'm making this more complicated than I need to now cause I really only needed a single selection box, and I don't think I will need to select multiple items. This OOP crap is encouraging me to overengineer everything! So throw out all that crap for allowing multiple selectors and go back to the single global in the type... Now I need to make a function to free the selectior... No wait, I don't need to free the selector, why am I bothering with that. I just need to create the seelctor and hide or show it as needed there's no reason to be creating and freeing it constantly. But I'd have done that in the first place if not for this stupid OOP once again encouraging me to overengineer stuff! Curse you OOP!" |
| ||
Skid: Thanks. There's another thing that concerns me now though, and that's that if I do that, then other libs I use that expect tlist to behave a certain way might not like it if for example, I override the reverselist. They might EXPECT a new list to be created. I don't know why they would or how that woudl affect them, but who knows. Just something elseto be concerned about. Can I make a type that works wirh EachIn and returns links instead of objects? Cause I'm thinking of taking Mark up on his suggestion of making my own list type that behaves the way I think it should. I probably shouldn't even explore that option though. It would make my life much easier but take a ton of time I don't have to reimplement linked lists. |
| ||
Argh, see? There I go again. This whole discussion is completely unneccessary and I'm even considering something as wasteful as making a new list type. I don't need to extend TList. All I want is the abiltiy to swap two fruit in my fruit list and I already put that functionality in the function. I don't NEED to make it pretty by adding it to TList so I don't have to look at the code! See, this is the true evil of OOP. It's a TIME SINK! |
| ||
Yeh, that trick is really only going to work in application / global scope, once you define a TList in a third party module I'm thinking the compiler will complain about not knowing which one to use when compiling applications.... I would encourage you also to implement a TFastList, you're going to get major speed ups if you do it properly that will resolve this issue of wanting to continue relations with TList in any shape or form. And yes the time sink rule applies until your project grows beyond a certain size, then OOP is more like using an architect when building a house. Expecting to learn best OOP practices from these forums is possibly the other problem I have with your current approach. If you want to program like God you're going to need some decent books for the big picture. |
| ||
It took me a week to write my sprite system in BlitzPlus. It took me a month to do it in Max. That's not a matter of procedural vs. object oriented paradigms, but rather a case of Fred Brooks "Second System Syndrome" - The second system an engineer designs is the most dangerous system he will ever design, since it will be disastrously overdesigned.Which going by your opening statements, is exactly what's happening here. If you want to program like God you're going to need some decent books for the big picture. And if you want a list, I refer you to our previous discussion on this topic. |
| ||
God programs in Forth. |
| ||
Surely he would program in FORTRAN, COBOL or LISP? (Depending on which kind of program he was writting at the time). |