![]() |
Forum Index : Microcontroller and PC projects : OOP (object oriented programming) in MMBASIC (kind of)
Page 1 of 3 ![]() ![]() |
|||||
Author | Message | ||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 528 |
Hello, I'm turning my head around this question. Of course I am aware of the fact that BASIC isn't about OOP at all. I know, BUT: C programming language isn't about OOP, too but it is kind of possible in C to do this. For example with this approach: C example Code: struct myStructure { int myNum; char myLetter; char myString[30]; // String }; int main() { struct myStructure s1; // Assign a value to the string using the strcpy function strcpy(s1.myString, "Some text"); // Print the value printf("My string: %s", s1.myString); return 0; } Is there a way in MMBASIC to do something similar to the STRUCT in C? I think this could be a great way for bigger programs to give it a better structure. At this point I am only aware of some worarounds with arrays... Greetings Daniel Edited 2025-03-22 01:27 by Amnesie |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
I don't understand C so a lot of the above doesn't mean a lot to me, but isn't this close to a FUNCTION ? You can feed it a set of variables and it returns a value? Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1121 |
Maybe something like the following? (Untested) dim string mystruct dim integer myaddr = PEEK(VARADDR mystruct) POKE INTEGER myaddr, 1234 ' store an integer in the "structure" MID$(mystruct,9,1) = "T" ' store character, 9th element MID$(mystruct,10,31) = "A string to store." i = PEEK(INTEGER myaddr) ' read the integer c = MID$(mystruct,9,1) ' read the character s$ = MID$(mystruct,10) ' read the string Which is indeed just a bunch of work-arounds with an array. Edited 2025-03-22 02:09 by vegipete Visit Vegipete's *Mite Library for cool programs. |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4249 |
That's not OOP, that's just a structured type - MMBasic doesn't have those, the best you can do is use a STRING type with the FIELD$() function or allocate integer arrays and PEEK and POKE around them as raw memory (as just illustrated by @vegipete plus he used MID$ to access string members). Both of which have significant performance implications. Naively OOP starts from structured types and then allows them to have embedded functions (which we call methods) that receive an implict 'this' parameter which is the instance of the structure they are operating on. Plus they tend to allow the structured types to be hierarchical (or introduce the concept of an "interface" and have those be hierarchical instead.) I have some ideas for adding structured types to MMB4L (from where Peter might decide they can be implemented more generally) and could probably manage objects in time ... however, if you're planning on holding your breath until then you should probably advise your relatives to send flowers ![]() Best wishes, Tom Edited 2025-03-22 02:13 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Marcel27![]() Regular Member ![]() Joined: 13/08/2024 Location: NetherlandsPosts: 77 |
Oh, no, please no oop in mmbasic, it's the worst invention ever made. |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
Oh - having structured data types would be really very nice and useful! ![]() Perhaps this would come at some future day? ![]() I suggest using the syntax as described for VBA: Type MyType MyName As String ' String variable stores a name. MyBirthDate As Date ' Date variable stores a birthdate. MySex As Integer ' Integer variable stores sex (0 for female, 1 for male). End Type https://learn.microsoft.com/en-us/office/vba/language/how-to/user-defined-data-type Extending to OOP wold be a further step, but could be added by just extending this syntax with the ability to define functions and subs (methods) within this "Type .. End Type" clause. I think I already saw some OOP BASIC variants using this syntax. In C++ structs are also "just classes" with the difference, that in structs all members default as public - so no need to define an aditional "Class .. End Class" clause. Adding public/private isn't mandatory and makes OOP "more complicated" for beginners. And single inheritance (as e.g. in Java) would be enough - multiple (as allowed in C++) leads to confusion very often.. This also applies to polymorphism! bfwolf Edited 2025-03-22 04:21 by bfwolf |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 528 |
@ vegipete Yes I came up with something similar.. But never thought about possible downsides when it comes to speed. @ Tom I know that this isn't real OOP, that's why I wrote "kind of" just that one understand what I am thinking of. @ bfwolf Yes, I also think it would be a nice addition to the MMBASIC syntax / possibilities. This way it would be possible to "wrap" more than just one datatype in a nice little structure. Especially when it comes to databases or textadventures I see a huge benefit for this... I also think, that going further isn't necessary (private.. polymorphism etc.) But I often wish to be able just to combine different datatypes into one "package" since I use this often in C. To give an example for a text adventure game, I need a lot of arrays to not get lost: Dim location(3)= "" 'array to store player location Dim exits(3)= "" 'array to store player exit points Dim itemsPlayer(10)= "" 'array to store player items Dim itemsRoom(10)= "" 'array to store items in the room 'etc... Dim integer room = 1 'current room of player It would be way more practical if I could say, that all these arrays belong to the room. This is just an example with a few things.. And multidimensional arrays make things worse when it comes to readability... I think. Greetings Daniel Edited 2025-03-22 05:01 by Amnesie |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
Why load MMBasic down with even more stuff that it doesn't need? :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 528 |
Because it is easier to maintain code. It is all about readability and not repeating myself again and again. In Python for example I do this: class Room(): def __init__(self, name, description): self.name = name self.description = description self.exits = {} self.items = [] self.npcs = [] And I think some kind of struct type isn't a bad idea. It must not be classes or such... But one datatype to wrap different datatypes into one package does make a whole lot of sense. Of course you can also write whole programs in assembly - so why using BASIC anyways.Greetings Daniel Edited 2025-03-22 05:15 by Amnesie |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
But BASIC is already a language, one that has grown over many years and has so far resisted OOP. ;) It was never designed to handle it and, generally, has performance issues (as an interpreter) that make it inefficient to add such foreign concepts. Modern languages such as RUST are designed with code security in mind. You can *never* get that in BASIC, C or Python. OOP is ideal for something like RUST, where the code can be built with secure partitioning and without the risk of the programmer breaking memory management, buffer overflows etc. Gluing OOP on top of BASIC can only bring tears in the long run. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 528 |
@ Mixtel90 Uhm... Visual BASIC has OOP and Python as an interpreted language also has OOP, but that isn't the point. As Tom already wrote I am not really talking about OOP more of an datatype called STRUCT. So... yeah sorry my Topic title was a bit of clickbait. Greetings Daniel Edited 2025-03-22 06:18 by Amnesie |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 527 |
I've been using arrays with constants to make the code a bit more readable (like a struct). Of course, you are limited to just using one variable type, but there is very little penalty (if any) for using Float vs Ints in MMBasic, so you could use Floats for the array - which would cover most scenarios (apart from Strings obviously). DIM INTEGER Ships(100,16) ' ShipId, then parameters (see next few lines) CONST SHIP_TYPE = 1 CONST SHIP_X = 2 CONST SHIP_Y = 3 CONST SHIP_ANGLE = 4 CONST SHIP_SHIELDN = 5 CONST SHIP_SHIELDE = 6 CONST SHIP_SHIELDS = 7 CONST SHIP_SHIELDW = 8 CONST SHIP_SHIELD_MAX = 9 CONST SHIP_HULL = 10 CONST SHIP_ENGINES = 11 CONST SHIP_WEAPONS = 12 CONST SHIP_SENSORS = 13 CONST SHIP_LOGIC = 14 ' 0=None, 1=Attacking, 2=Fleeing CONST SHIP_LOGIC2 = 15 ' Used as part of the logic CONST SHIP_POWER = 16 So, if I want to get the X location of ship #5, then I just use Ships(5,SHIP_X) It's not as neat as a struct. And while Structs would be an amazing addition to MMBasic, I am aware that it's probably a bit of a nightmare to add in, and I am already sooo grateful for the amazing features MMBasic has already given us, that I can live with this. Edited 2025-03-22 13:29 by PeteCotton |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
If you set up some constants: CONST num.of.ships = 11 CONST TYPE = 1 CONST XPOS = 2 CONST YPOS = 3 CONST ANGLE = 4 etc. Then define an array: DIM SHIP(num.of.ships,16) You can then use the values as: SHIP(1,TYPE) SHIP(4,ANGLE) etc. You may be able to re-use the CONS values for other things. e.g, DIM SPACEMINE(12,16) if SPACEMINE(3,XPOS) = 0 then mine.is.inactive It would help to keep shared CONST values in the lowest numbers as then any arrays could be smaller. i.e. if CONST XPOS = 1 and CONST XPOS = 2 then you could use DIM SPACEMINE(12,2) . Edited 2025-03-22 18:10 by Mixtel90 Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
Arrays with "named indices" are one possibility, but this is more of a "würgaround" than a workaround. For readers unfamiliar with German language: This is a play on words... "würgen" = "to choke." Furthermore, such arrays naturally only accommodate values of the same type, which would require creating multiple arrays to store different types of information. And of course pass multiple args to subs and functions for the same "bundle".. CONST num.of.ships = 11 CONST num.of.ship_int = 4 CONST TYPE = 1 CONST XPOS = 2 CONST YPOS = 3 CONST ANGLE = 4 CONST num.of.ship_str = 2 CONST NAME = 1 CONST OWNER = 2 ' etc. ' Then define arrays: DIM SHIP_INT(num.of.ships,num.of.ship_int) As integer DIM SHIP_STR(num.of.ships,num.of.ship_str) As string ' You can then use the values as: SHIP_INT(1,TYPE) = 3 SHIP_STR(1,OWNER) = "Geoff" SHIP_INT(4,ANGLE) = 88 'etc. Structs (Records in Pascal) are simply the most elegant way to do this, and you can create arrays of structs, which then "bundle" the information in each element. You can also pass the entire struct to procedures and functions as an argument (e.g., by reference). Unfortunately, the '.' character is permitted as part of variable names and therefore cannot simply be used as a separator between struct instance names and member names. A different separator might have to be found that isn't already used as a token or operator. Perhaps the '#' character? Extending structs with OO by adding methods and inheritance would open up entirely new programming techniques, but that would be the icing on the cake - and it doesn't necessarily have to be that way. |
||||
homa![]() Guru ![]() Joined: 05/11/2021 Location: GermanyPosts: 459 |
To use the '.' character, you could give the command via OPTION in the program (analogous to OPTION EXPLICIT), but I don't think OOP comes in MMBasic on a microprocessor, but what do I know. Matthias |
||||
LeoNicolas![]() Guru ![]() Joined: 07/10/2020 Location: CanadaPosts: 499 |
I think the question is not about OOP, but regarding data structures. There is no struct like structures in basic. For my game Knightmare I'm using the same approach as PeteCotton. I'm allocating arrays to store what I want. https://github.com/leonicolas/knightmare-cmm2/blob/main/global.inc |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4249 |
Whilst I think structured types would be of great benefit (not least because they should be faster than the approach using arrays with named constants which require two variable lookups) I'm not convinced about the need for OOP ... except that once you have proper structured types, including the ability to pass them by reference to functions then I believe the jump to implement OOP is not that great. However I again caution against holding of breath (unless Peter decides to work one of his miracles) as adding a new fundamental type to MMBasic is a very significant piece of work with plenty of opportunity to destablise MMBasic for several months. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
I also agree that the step to OOP would be another big one, and that it wouldn't be necessary. And yes - in "classic" BASIC dialects, the concept of "user-defined types" (UDT) isn't known - but in many modern dialects, it is: VBA: https://learn.microsoft.com/en-us/office/vba/language/how-to/user-defined-data-type FreeBasic: https://freebasic.net/wiki/ProPgUDTs XC=BASIC (for C64 etc.): https://xc-basic.net/doku.php?id=v3:udt And all three use the same approach and syntax.. FreeBasic even supports pointers! But let this be "future music".. ![]() bfwolf. Edited 2025-03-24 00:47 by bfwolf |
||||
toml_12953 Guru ![]() Joined: 13/02/2015 Location: United StatesPosts: 390 |
Heck, I'd settle for just having user-defined data types. Fixed length records of user defined types would make handling RANDOM files much cleaner, too. |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4852 |
All, If you think OOB (Out Of the Box) in stead of OOP, you can implement structures already in MMBasic. Assume you want this Struct address{ STREET as string 12 NUMBER as integer } Define Peter type address Peter.street = "churchroad" Peter.number = 12 What about using following technique DIM street$(nn) length 12 DIM number%(nn) Peter = 0 : Charly = 1 : Karen = 2 street$(Peter)="churchroad" number%(Peter)=12 So instead of Peter.street you use street$(Peter). Volhout Edited 2025-03-24 03:38 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
Page 1 of 3 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |